何时使用Serializer的create()和ModelViewset' s create()perform_create()

时间:2016-12-12 03:59:35

标签: python django serialization django-rest-framework

我想澄清django-rest-framework关于创建模型对象的给定文档。到目前为止,我发现有3种方法可以处理此类事件。

  1. Serializer的create()方法。这是documentation

    class CommentSerializer(serializers.Serializer):
    
        def create(self, validated_data):
            return Comment.objects.create(**validated_data)
    
  2. ModelViewset create()方法。 Documentation

    class AccountViewSet(viewsets.ModelViewSet):
    
        queryset = Account.objects.all()
        serializer_class = AccountSerializer
        permission_classes = [IsAccountAdminOrReadOnly]
    
  3. ModelViewset perform_create()方法。 Documentation

    class SnippetViewSet(viewsets.ModelViewSet):
    
        def perform_create(self, serializer):
            serializer.save(owner=self.request.user)
    
  4. 这三种方法很重要,具体取决于您的应用环境。

    但是我们什么时候需要使用每个create() / perform_create()函数?另一方面,我发现有一个帐户,即为单个帖子请求调用了两个创建方法,模型视图的create()和序列化程序的create()

    希望任何人都能分享他们的一些知识来解释,这对我的开发过程肯定会非常有帮助。

1 个答案:

答案 0 :(得分:68)

  1. 您可以使用SUMPRODUCT将任何额外的详细信息添加到对象中,然后将“prod”值保存到每个模型字段中,就像create(self, validated_data)一样。理想情况下,您希望仅在一个位置执行此类形式的“刺激”,因此**validated_data中的create方法是最佳位置。除此之外,您可能还想在将帐户保存到自己的数据库之前调用外部apis来创建用户帐户。您应该将此CommentSerializer功能与create结合使用。总是想 - “薄视图,厚序列化器”。
  2. 示例:

    ModelViewSet
    1. def create(self, validated_data): email = validated.data.get("email", None) validated.pop("email") # Now you have a clean valid email # You might want to call an external API or modify another table # (eg. keep track of number of accounts registered.) or even # make changes to the email format. # Once you are done, create the instance with the validated data return models.YourModel.objects.create(email=email, **validated_data) 中的create(self, request, *args, **kwargs)函数在ModelViewSet类中定义,该类是CreateModelMixin的父级。 ModelViewSet的主要功能是:

      CreateModelMixin
    2. 如您所见,上面的def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) def perform_create(self, serializer): serializer.save() 函数负责在序列化程序上调用验证并生成正确的响应。这背后的美妙之处在于,您现在可以隔离您的应用程序逻辑,而不关心平凡和重复的验证调用以及处理响应输出:)。这与在序列化程序中找到的create(您的特定应用程序逻辑可能驻留在其中)相结合非常有效。

      1. 现在你可能会问,为什么我们只用一行代码就有一个单独的create(self, validated_data)函数!?!?那么,这背后的主要原因是在调用perform_create(self, serializer)函数时允许自定义。您可能希望在调用save 之前提供额外数据(例如save ,如果我们没有serializer.save(owner=self.request.user),则您必须覆盖{{1而这恰好击败了让mixin做重而枯燥的工作的目的。
      2. 希望这有帮助!