DRF在viewset或serializer中创建方法

14
什么是在DRF视图集中定制“create”方法和在序列化器中定制它的区别? 我了解序列化器负责反序列化数据,即以POST查询中呈现数据的方式; 但是,在序列化器中也可以创建相关字段中的对象。
区别在于定制“create”方法将影响视图集中所有使用该方法的行为,而定制序列化器将仅影响使用该序列化器的视图。此外,在视图集中使用自定义“create”方法可能需要额外处理验证和错误处理,因为您必须手动执行此操作,而序列化器则会自动处理这些任务。
#views.py
def create(self, request):
    pass

#serializer.py
def create(self, validated_data):
    return Model.objects.create(**validated_data)

何时应该自定义 views/create 而不是 serializer/create?


我自己喜欢使用Viewset,因为请求对象(如果需要)已经存在,我不需要编写额外的代码来传递额外的参数给序列化器。我也喜欢将两种逻辑分离开来,因此在Viewset级别上创建是为了用于实际在后端创建记录的请求,而在序列化器级别上创建是为了从序列化后的数据创建对象并返回,以供您进行必要的操作。 - devdob
1个回答

31

create方法来自Viewset

该方法处理视图中的POST请求逻辑,默认情况下会执行以下操作:

  • 使用请求中作为有效负载的任何数据实例化序列化程序
  • 在序列化程序上执行is_valid方法
  • 通过调用序列化器上的.save()方法执行实际创建
  • 返回带有序列化数据和201状态的视图Response

您真正需要覆盖Viewset上的create方法,只有当您需要从视图本身将内容发送到序列化程序时,才可以覆盖perform_create。 默认情况下它执行serializer.save()。例如,如果您想要发送请求中的用户,可以执行以下操作:

    def perform_create(self, serializer):
        # here you will send `created_by` in the `validated_data` 
        serializer.save(created_by=self.request.user)

注意:幕后save方法将使用validated_data在序列化器上执行create方法。

来自序列化器的create方法

此方法仅使用validated_data创建实际的模型实例。 如果您需要创建相关对象,则可以重写此方法,例如以下内容:

   def create(self, validated_data):
        items_data = validated_data.pop('items')

        # similar to Parent.objects.create(**validated_data)
        parent = super().create(**validated_data)

        for item_data in items_data:
            Item.objects.create(parent=parent, **item_data)
        return parent

所以,在这里,您正在发送一个有效载荷,其中包含有关Parent对象的数据以及items列表及其表示形式,因此现在create方法还将创建项目并将其与父实例链接起来。

总结一下:

  • 在视图集中,create方法处理请求-响应流程
  • 在序列化程序中,create方法使用经过验证的数据处理模型实例的创建。

我如何在这里返回一个自定义消息,比如"创建成功"? - surya raj
你为什么需要那个消息?如果成功创建,视图本身将返回带有状态码201的HTTP响应,您可以使用它。 - Gabriel Muj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接