前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Django Rest Model 中 User 字段的插入问题

Django Rest Model 中 User 字段的插入问题

作者头像
fanzhh
发布2019-08-20 11:28:49
发布2019-08-20 11:28:49
1.7K00
代码可运行
举报
运行总次数:0
代码可运行

使用Django Rest作为后端在做的项目中,Model是这样的:

代码语言:javascript
代码运行次数:0
运行
复制
class Sample(models.Model):
    ...
    creater = models.ForeignKey(User, on_delete=models.CASCADE)
    ...

Serializers是这样:

代码语言:javascript
代码运行次数:0
运行
复制
class SampleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Sample
        fields = (...,'creater')

Views是这样:

代码语言:javascript
代码运行次数:0
运行
复制
class SampleList(generics.ListCreateAPIView):
    queryset = Sample.objects.all()
    serializer_class = SampleSerializer
    permission_classes = (IsOwnerOrReadOnly,)

    def perform_create(self, serializer):
        ...
        serializer.save(creater=self.request.user,...)

问题是,我在执行插入的时候,总是提示:

代码语言:javascript
代码运行次数:0
运行
复制
{"creater": ["This field is required."]}

百思不得其解,因为明明通过creater=self.request.user赋值了啊。 后来在Model中,将creater字段修改为

代码语言:javascript
代码运行次数:0
运行
复制
creater = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)

问题解决。

但这是为什么呢?谷歌后发现:

The perform_create method is called by your View's create method after serializer validation. At this stage, DRF will have found and flagged the missing user field.

原来视图中的perform_create操作晚于serializer的校验。上面的代码中,perform_create前DRF已经发现creater字段的缺失。

来看看rest_framework源码

代码语言:javascript
代码运行次数:0
运行
复制
class CreateModelMixin(object):
    """
    Create a model instance.
    """
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
        serializer.save()

    def get_success_headers(self, data):
        try:
            return {'Location': str(data[api_settings.URL_FIELD_NAME])}
        except (TypeError, KeyError):
            return {}

解决这个问题的方法有多种,除了上面的null=True, blank=True之外,还可以:

  • serializer中设置这个字段readonly=True,或
  • serializer中重载validate_user,或
  • 使用DFR的currentuserdefault校验器。

参考地址

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.05.30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档