Python Django rest 框架:覆盖 ModelSerializer 中的 create() 传递额外参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30650008/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 08:45:25  来源:igfitidea点击:

Django rest framework: override create() in ModelSerializer passing an extra parameter

pythondjangodjango-rest-frameworkoverriding

提问by floatingpurr

I am looking for a way to properly ovverride the default .create()method of a ModelSerializerserializer in Django Rest Framework for dealing with an extra parameter.

我正在寻找一种方法来正确覆盖Django Rest Framework 中序列化程序的默认.create()方法,ModelSerializer以处理额外的参数。

In my original Django model I have just overridden the default.save()method for managing an extraparam. Now .save()can be called also in this way: .save(extra = 'foo').

在我的原始 Django 模型中,我刚刚覆盖了.save()管理extra参数的默认方法。现在.save()也可以叫做以这样的方式.save(extra = 'foo')

I have to create a ModelSerializermapping on that original Django model:

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

from OriginalModels.models import OriginalModel
from rest_framework import serializers

class OriginalModelSerializer(serializers.ModelSerializer):

    # model fields
    class Meta:
        model = OriginalModel

But in this way I can't pass the extraparam to the model .save()method.

但是这样我无法将extra参数传递给模型.save()方法。

How can I properly override the .create()method of my OriginalModelSerializerclass to take (eventually) this extraparam into account?

如何正确覆盖.create()我的OriginalModelSerializer类的方法以(最终)extra考虑这个参数?

采纳答案by Alex T

Hmm. this might not be the perfect answer given I don't know how you want to pass this "extra" in (ie. is it an extra field in a form normally, etc)

唔。这可能不是完美的答案,因为我不知道您想如何将这个“额外”传入(即它是否通常是表单中的额外字段等)

What you'd probably want to do is just represent foo as a field on the serializer. Then it will be present in validated_datain create, then you can make createdo something like the following

您可能想要做的只是将 foo 表示为序列化程序上的一个字段。然后它将出现在validated_datain 中create,然后您可以create执行以下操作

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

You'd probably want to look at the default implementation of create for some of the other things it does though (like remove many-to-many relationships, etc.).

您可能想查看 create 的默认实现,以了解它所做的其他一些事情(例如删除多对多关系等)。

回答by davmor

You can now do this in the view set (threw in user as a bonus ;) ):

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

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')

That way the Serializer can stay generic, i.e.:

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

class OriginalModelSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = OriginalModel
        fields = '__all__'