Let's say I have these models/classes:
class User(models.Model):
id = models.AutoField. . .
group = models.ForeignKey(
Group,
. . .
)
. . .
class Group(models.Model):
id = models.AutoField. . .
name = models.CharField. . .
. . .
In a custom logging function called when there is a change being made, I do this:
obj = # object/model being updated; in this case: User
old_values = {}
new_values = {}
for i in range(len(form.changed_data)):
vname = obj._meta.get_field(form.changed_data[i]).verbose_name
old_values.update(
{ vname: form[form.changed_data[i]].initial }
)
new_values.update(
{ vname: form.cleaned_data[form.changed_data[i]] }
)
That leads to this output:
old_values = {'Group': 2}
new_values = {'Group': <Group: New Group Name>}
Looks like form.initial
uses the id
while form.cleaned_data
uses some kind of unsightly object name format.
Neither are desired. I want the output to look like this:
old_values = {'Group': 'Old Group Name'}
new_values = {'Group': 'New Group Name'}
How do I do this? I cannot explicitly import the model name and use it. User
and Group
are merely two of dozens of models that must be treated non-explicitly in this generic logging function.
I've tried apps.get_model()
, get_object_or_404()
, and other methods, but nothing has been working for me so far.
The value of Foreign Key in the default form is the PK of the model.
# old_values = {'Group': 2}
group = Group.objects.get(pk=old_values['Group'])
new_values = {'Group': group.name}
I still do not know how to do what I tried above, but I solved my problem another way.
To start, each object has a meta variable that references its object class. Using that, we can obtain a list of fields for any given object.
for field in obj._meta.get_fields():
value = getattr(obj, field.name, None)
You can check each field for whatever specifications you have, like if they should be ignored like ID fields, should be censored like password fields, or is a ManyToManyField etc.
if isinstance(field, ManyToManyField):
values = []
for obj in value.all():
values.append(str(obj))
Depending on what the value is, you may want repr(value)
, str(value)
, str(object)
, or just plain value
.
What I did was create a function get_values(object) that utilized the above to return a standardized list of stuff. Sending that function the objects during the logging process worked just fine.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.