在 Django 模型中使用 update() 时如何跟踪更改
How to track changes when using update() in Django models
我试图在字段更改时跟踪更改。
每当我使用 .save() 方法时,我都可以在 Django 管理历史记录中看到更改,但是每当我使用 .update() 方法时,它都不会记录我在对象中所做的任何更改。
我想使用 update() 因为它可以同时更改多个字段。它使代码更简洁、更高效(一次查询,一行...)
现在我正在使用这个:
u = Userlist.objects.filter(username=user['username']).update(**user)
我可以看到所有的变化
u = Userlist.objects.get(username=user['username'])
u.lastname=lastname
u.save()
我也在使用 django-simple-history 查看 changes.setup。
来自docs:
Finally, realize that update()
does an update at the SQL level and,
thus, does not call any save()
methods on your models, nor does it
emit the pre_save
or post_save
signals (which are a consequence of
calling Model.save()
)
update()
在数据库级别工作,因此当通过 .update(...)
.
应用更新时,Django 管理员无法跟踪更改
如果您仍想跟踪更新的变化,您可以使用:
for user in Userlist.objects.filter(age__gt=40):
user.lastname = 'new name'
user.save()
然而,这更昂贵,如果唯一的好处是通过管理历史跟踪更改,则不建议这样做。
这是我处理这个问题的方法,到目前为止效果很好:
# get current model instance to update
instance = UserList.objects.get(username=username)
# use model_to_dict to convert object to dict (imported from django.forms.models import model_to_dict)
obj_dict = model_to_dict(instance)
# create instance of the model with this old data but do not save it
old_instance = UserList(**obj_dict)
# update the model instance (there are multiple ways to do this)
UserList.objects.filter(username=username).update(**user)
# get the updated object
updated_object = UserList.objects.get(id=id)
# get list of fields in the model class
my_model_fields = [field.name for field in cls._meta.get_fields()]
# get list of fields if they are different
differences = list(filter(lambda field: getattr(updated_object, field, None)!= getattr(old_instance, field, None), my_model_fields))
差异变量将为您提供两个实例之间不同的字段列表。我还发现添加我不想检查差异的模型字段很有帮助(例如,我们知道 updated_date 将始终更改,因此我们不需要跟踪它)。
skip_diff_fields = ['updated_date']
my_model_fields = []
for field in cls._meta.get_fields():
if field.name not in skip_diff_fields:
my_model_fields.append(field.name)
我试图在字段更改时跟踪更改。
每当我使用 .save() 方法时,我都可以在 Django 管理历史记录中看到更改,但是每当我使用 .update() 方法时,它都不会记录我在对象中所做的任何更改。
我想使用 update() 因为它可以同时更改多个字段。它使代码更简洁、更高效(一次查询,一行...)
现在我正在使用这个:
u = Userlist.objects.filter(username=user['username']).update(**user)
我可以看到所有的变化
u = Userlist.objects.get(username=user['username'])
u.lastname=lastname
u.save()
我也在使用 django-simple-history 查看 changes.setup。
来自docs:
Finally, realize that
update()
does an update at the SQL level and, thus, does not call anysave()
methods on your models, nor does it emit thepre_save
orpost_save
signals (which are a consequence of callingModel.save()
)
update()
在数据库级别工作,因此当通过 .update(...)
.
如果您仍想跟踪更新的变化,您可以使用:
for user in Userlist.objects.filter(age__gt=40):
user.lastname = 'new name'
user.save()
然而,这更昂贵,如果唯一的好处是通过管理历史跟踪更改,则不建议这样做。
这是我处理这个问题的方法,到目前为止效果很好:
# get current model instance to update
instance = UserList.objects.get(username=username)
# use model_to_dict to convert object to dict (imported from django.forms.models import model_to_dict)
obj_dict = model_to_dict(instance)
# create instance of the model with this old data but do not save it
old_instance = UserList(**obj_dict)
# update the model instance (there are multiple ways to do this)
UserList.objects.filter(username=username).update(**user)
# get the updated object
updated_object = UserList.objects.get(id=id)
# get list of fields in the model class
my_model_fields = [field.name for field in cls._meta.get_fields()]
# get list of fields if they are different
differences = list(filter(lambda field: getattr(updated_object, field, None)!= getattr(old_instance, field, None), my_model_fields))
差异变量将为您提供两个实例之间不同的字段列表。我还发现添加我不想检查差异的模型字段很有帮助(例如,我们知道 updated_date 将始终更改,因此我们不需要跟踪它)。
skip_diff_fields = ['updated_date']
my_model_fields = []
for field in cls._meta.get_fields():
if field.name not in skip_diff_fields:
my_model_fields.append(field.name)