【问题标题】:Django rest framework: override create() in ModelSerializer passing an extra parameterDjango rest 框架:在 ModelSerializer 中覆盖 create(),传递一个额外的参数
【发布时间】:2015-08-19 10:17:29
【问题描述】:

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

在我原来的 Django 模型中,我刚刚重写了用于管理 extra 参数的 default.save() 方法。现在.save()也可以这样调用:.save(extra = 'foo')

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

from OriginalModels.models import OriginalModel
from rest_framework import serializers

class OriginalModelSerializer(serializers.ModelSerializer):

    # model fields
    class Meta:
        model = OriginalModel

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

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

【问题讨论】:

    标签: python django django-rest-framework overriding


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 问题是“额外”参数不是我OrginalModel 的字段。据我所知,如果没有映射到OrginalModel 的任何常规字段,则无法将字段添加到ModelSerializer
    • 您需要先从validated_data 弹出foo 字段,然后再将其传递给模型构造函数,那么这个答案应该可以工作。
    • 确保包含在 ModelSerializer' 'create' 方法中定义的所有其他代码:github.com/encode/django-rest-framework/blob/3.9.0/… 否则上面的代码会丢失一些预定义的功能。
    【解决方案2】:

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

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

    这样序列化器可以保持通用,即:

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

    【讨论】:

    • 你什么时候把这个逻辑放在视图、序列化器、模型管理器甚至信号中?
    • 当您需要分离功能时。我使用视图,因为它允许多个视图使用相同的序列化程序。我对模型更严格一些,因为模型中的逻辑应该适用于系统范围——REST 是一个特定的用例。信号真的是用来解耦的——这对于这个应用程序来说可能太多了,也信号复杂的支持,我有足够的事情做而不增加支持负担。但是,有不止一种方法可以做到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-03
    • 2014-09-08
    • 2019-03-24
    • 1970-01-01
    • 2018-08-02
    • 2015-05-15
    • 2019-03-02
    相关资源
    最近更新 更多