2

每当更改字段时,我都会尝试跟踪更改。

每当我使用 .save() 方法时,我都可以看到 Django Admin History 中的更改,但每当我使用 .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。

4

2 回答 2

2

文档

最后,意识到update()在 SQL 级别进行更新,因此不会调用save()模型上的任何方法,也不会发出pre_saveorpost_save信号(这是调用的结果Model.save()

update()在数据库级别工作,因此 Django 管理员无法在通过.update(...).

如果您仍想跟踪更新的更改,您可以使用:

for user in Userlist.objects.filter(age__gt=40):
    user.lastname = 'new name'
    user.save()

但是,如果唯一的好处是通过管理历史记录跟踪更改,则这样做会更加昂贵并且不建议使用。

于 2016-06-21T18:25:56.487 回答
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))

差异变量将为您提供两个实例之间不同的字段列表。我还发现添加我不想检查差异的模型字段很有帮助(例如,我们知道 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)
于 2019-04-09T16:19:44.930 回答