【问题标题】:django rest add data to serializer when savingdjango rest 保存时将数据添加到序列化程序
【发布时间】:2017-07-09 19:53:48
【问题描述】:

我想做以下事情:

models.py

class MyModel(TimeStampedModel, models.Model):
    name = models.CharField(max_length=100)
    owner = models.ForeignKey(settings.AUTH_USER_MODEL)

序列化器.py

class MyModelSerializerCreate(serializers.ModelSerializer):

    class Meta:
        model = MyModel
        fields = (
            'name',
        )

我想将request.user 中的当前用户添加为所有者。 目前我通过用户更新 request.data 直接在我的视图中添加它,然后将更新的数据传递给我的序列化程序。

    data = request.data
    # Add owner to data
    data["owner"] = request.user.pk
    serializer = self.get_serializer(data=data)
    serializer.is_valid(raise_exception=True)
    self.perform_create(serializer)
    headers = self.get_success_headers(serializer.data)

我想直接在我的序列化程序中执行此操作,但找不到正确执行此操作的方法,因为它对我来说像是数据验证。这是一个好主意吗 ?我应该将此逻辑保留在我的视图中还是将其移至我的序列化程序?

【问题讨论】:

    标签: django serialization django-rest-framework


    【解决方案1】:

    您可以从序列化程序上下文中获取用户:

    self.context['request'].user
    它是从方法get_serializer_context 传递的,该方法最初是在GenericAPIView 中创建的:

    class GenericAPIView(APIView):
        ....
        def get_serializer_context(self):
            """
            Extra context provided to the serializer class.
            """
            return {
                'request': self.request,
                'format': self.format_kwarg,
                'view': self
            }  
    

    在序列化程序中,您需要重写 create 方法:

    class MyModelSerializerCreate(serializers.ModelSerializer):
    
        class Meta:
            model = MyModel
            fields = ('name', )
     
        def create(self, validated_data):
            validated_data['owner'] = self.context['request'].user
            return super(MyModelSerializerCreate, self).create(validated_data)
    

    如果您需要与User 模型进行一些特殊交互,您还可以覆盖updatedelete 方法。

    【讨论】:

    • 嗯,这看起来不错,但它覆盖了 ModelSerializer 的 create 函数,该函数做了很多事情,例如管理 many_to_many 关系。如果我可以将我的用户直接放入验证数据中,那就太酷了
    • @v.thorey 这样您就可以更新validated_data,然后调用super 以提供所有默认行为,或者您可以在视图中使用perform_create 方法。我会更新我的答案
    • @IvanSemochkin 我有同样的问题,但你的答案不知何故对我不起作用。我基本上想做:def perform_create(self, serializer): serializer.save(user=self.request.user) 但如果我按照你的回答做,我会得到错误:"user": [ "This field is required." ]
    • @J.Hesters 也许你在fields 元组中有一个user,所以validate 方法希望你在create 之前提供一个用户
    【解决方案2】:

    不幸的是,我没有声誉点来评论上面的@ivan-Semochkin 帖子,但最后一行不应该是:

    return super(MyModelSerializerCreate, self).create(validated_data)
    

    【讨论】:

      【解决方案3】:

      Ivan Semochkin 的解决方案对我不起作用,因为它从未进入序列化程序的 create() 方法。由于request.data字段是不可变的,你需要复制它然后扩展它。

      from django.http import HttpRequest
      from rest_framework.request import Request
      
      class MyModelViewSet(ModelViewSet):
          def _extend_request(self, request):
              data = request.POST.copy()
              data['owner'] = request.user
              request_extended = Request(HttpRequest())
              request_extended._full_data = data
      
          def create(self, request, *args, **kwargs):
              request_extended = self._extend_request(request)
              return super().create(request_extended, *args, **kwargs)
      

      【讨论】:

        猜你喜欢
        • 2018-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-12
        • 2014-09-16
        • 1970-01-01
        • 2021-04-09
        相关资源
        最近更新 更多