Django rest框架:在ModelSerializer中覆盖create(),传递一个额外的参数

flo*_*urr 10 python django overriding django-rest-framework

我正在寻找一种方法来正确地替换Django Rest Framework .create()中的ModelSerializer序列化器的默认方法来处理额外的参数.

在我原来的Django模型中,我刚刚覆盖了.save()管理extraparam 的默认方法.现在.save()也可以用这种方式调用:.save(extra = 'foo').

我必须ModelSerializer在原始的Django模型上创建一个映射:

from OriginalModels.models import OriginalModel
from rest_framework import serializers

class OriginalModelSerializer(serializers.ModelSerializer):

    # model fields
    class Meta:
        model = OriginalModel
Run Code Online (Sandbox Code Playgroud)

但是这样我就无法将extraparam 传递给模型.save()方法.

我怎样才能正确地覆盖.create()我的OriginalModelSerializer类的方法来考虑(最终)这个extra参数?

小智 16

嗯.这可能不是一个完美的答案,因为我不知道你想如何传递这个"额外"(即它是一个正常形式的额外字段,等等)

您可能想要做的只是将foo表示为序列化程序中的字段.然后,它会出现在validated_datacreate,那么你可以让create像做以下

def create(self, validated_data):
    obj = OriginalModel.objects.create(**validated_data)
    obj.save(foo=validated_data['foo'])
    return obj
Run Code Online (Sandbox Code Playgroud)

您可能希望查看create的默认实现,但它会执行其他一些操作(例如删除多对多关系等).

  • 在将它传递给模型构造函数之前,你需要从`validated_data`中弹出`foo`字段,然后这个答案应该有效. (6认同)
  • 问题是"额外"参数不是我的'OrginalModel`字段.据我所知,如果没有映射到`OrginalModel的任何常规字段',就没有办法向`ModelSerializer`添加字段. (2认同)

dav*_*mor 10

您现在可以在视图集中执行此操作(作为奖励扔给用户 ;) ):

class OriginalModelViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows OriginalModel classes to be viewed or edited.
    """
    serializer_class = OriginalModelSerializer
    queryset =  OriginalModel.objects.all()
    def perform_create(self, serializer):
        user = None
        if self.request and hasattr(self.request, "user"):
            user = self.request.user
        serializer.save(user=user, foo='foo')
Run Code Online (Sandbox Code Playgroud)

这样 Serializer 就可以保持通用,即:

class OriginalModelSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = OriginalModel
        fields = '__all__'
Run Code Online (Sandbox Code Playgroud)