Django REST Framework,pre_save()和serializer.is_valid(),它们如何工作?

时间:2013-11-15 05:08:22

标签: python django rest django-rest-framework

我需要将用户附加到请求中,这似乎是一件相当常见的事情,但事实证明这几乎是不可能的。

Django REST框架的文档建议使用序列化程序类的pre_save方法,但是在调用serializer.is_valid()时它不会被调用,这使得它没有用户的价值字段序列化程序验证失败。

我已经看到了一些建议,但它们看起来像疯狂的黑客和/或不起作用。另外,我觉得这是一个太常见的任务,真正需要我看到人们建议的所有东西。我不能成为唯一需要将用户附加到REST请求中创建的对象的人。

5 个答案:

答案 0 :(得分:5)

假设您正在使用此处描述的身份验证机制之一(或Django Auth):

http://django-rest-framework.org/api-guide/authentication.html,你有一个

request.user对象。

创建序列化程序时,将其从请求中拉出/在实例化时将其传入。

MySerializer(data={"user": request.user, "otherField"=... })

如果你这样做:

MySerializer(data=request.DATA)

您需要复制request.DATA对象:

from django.utils.datastructures import MultiValueDict
...
data = MultiValueDict(request.DATA)
data['user'] = request.user
MySerializer(data=data)

答案 1 :(得分:4)

pre_save之后但在将实例保存到数据库之前调用

is_valid。您需要覆盖验证(在该用户序列化程序字段上使用def get_validation_exclusions(self):,因为您将在pre_save中修复验证问题。请参阅我之前的答案:

Django REST Framework serializer field required=false

我向DRF的作者提出了这个问题,他们将调查一个更可行的解决方案。

答案 2 :(得分:2)

事实证明问题是我使用ListAPIView作为我的视图类的基类,并且它没有定义pre_save方法。当我添加一些已定义的mixin时,一切都开始工作了。

很奇怪,很多基础教程中使用的东西都不支持这样的基本功能,但是生活和学习。

答案 3 :(得分:1)

此问题的最佳解决方案是在序列化程序中将pre_save中填充的必填字段标记为read_only_fields

为此,请将以下内容添加到序列化程序类:

class MySerializer(serializers.ModelSerializer):
    ...
    class Meta:
        ...
        read_only_fields = ['user', 'my_other_field', ...]

答案 4 :(得分:1)

在新版本的DRF(3.x)中,pre_save被替换为 perform_createperform_updateReference