我很好奇是否有办法在使用Django Rest Framework保存对象后查看对象的更改。我有一些特殊的行为,我需要检查一个字段是否已经从我希望使用post_save
上的generics.RetrieveUpdateDestroyAPIView
处理的原始值更改。
我的第一个想法是使用pre_save
进行检查,但似乎pre_save
的对象参数已经应用了更改。
答案 0 :(得分:11)
django rest framework version 2.3.12的OLD ANSWER:
要检查更新时是否有任何更改,您必须将未更改的模型实例(即self.object)与已更改的模型实例(serializer.object)进行比较。
传递给pre_save方法的object参数是serializer.object,它尚未保存在数据库中并带有新的更改。
未更改的模型实例是self.object,它使用self.get_object_or_none()从数据库中获取。将它与pre_save方法中的obj参数进行比较。
def pre_save(self,obj):
unchanged_instance = self.object
changed_instance = obj
..... # comparison code
django rest framework 3.3的新答案:
pre_save和post_save不再有效 http://www.django-rest-framework.org/topics/3.0-announcement/#generic-views
现在您可以在perform_update方法中放置任何预保存或后保存逻辑。例如:
def perform_update(self, serializer):
# NOTE: serializer.instance gets updated after calling save
# if you want to use the old_obj after saving the serializer you should
# use self.get_object() to get the old instance.
# other wise serializer.instance would do fine
old_obj = self.get_object()
new_data_dict = serializer.validated_data
# pre save logic
if old_obj.name != new_data_dict['name']:
do_something
.....
new_obj = serializer.save()
# post save logic
......
答案 1 :(得分:1)
我可以在model_utils FieldTracker的帮助下完成此操作。您可以在相关模型上安装跟踪器,然后在pre_save
(post_save
已经太晚了)您可以执行此操作:
def pre_save(self, obj):
if hasattr(obj, 'tracker'):
self.changed_fields = obj.tracker.changed()
else:
self.changed_fields = None
changed_fields
将如下所示:{'is_public': False, 'desc': None}