我试图在字段更改时跟踪更改。
每当我使用.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。
答案 0 :(得分:0)
来自docs:
最后,意识到
update()
在SQL级别进行更新, 因此,不会在您的模型上调用任何save()
方法,也不会 发出pre_save
或post_save
信号(这是...的结果) 致电Model.save()
)
update()
适用于数据库级别,因此当通过.update(...)
应用更新时,Django管理员无法跟踪更改。
如果您仍想跟踪更新的更改,可以使用:
for user in Userlist.objects.filter(age__gt=40):
user.lastname = 'new name'
user.save()
然而,这是更昂贵的,如果唯一的好处是通过管理历史跟踪更改,则不建议这样做。
答案 1 :(得分:0)
这是我的处理方式,到目前为止效果良好:
# 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))
difference变量将为您提供两个实例之间不同的字段列表。我还发现添加不希望检查差异的模型字段很有帮助(例如,我们知道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)