何时使用 Serializer 的 create() 和 ModelViewset 的 perform_create() [英] When to use Serializer's create() and ModelViewset's perform_create()

查看:12
本文介绍了何时使用 Serializer 的 create() 和 ModelViewset 的 perform_create()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to clarify the given documentation of Django-rest-framework regarding the creation of a model object. So far I have found that there are 3 approaches on how to handle such events.

  1. 序列化程序的 create() 方法.这是文档

class CommentSerializer(serializers.Serializer):

    def create(self, validated_data):
        return Comment.objects.create(**validated_data)

  • ModelViewset create() 方法.文档

    class AccountViewSet(viewsets.ModelViewSet):
    
        queryset = Account.objects.all()
        serializer_class = AccountSerializer
        permission_classes = [IsAccountAdminOrReadOnly]
    

  • ModelViewset perform_create() 方法.文档

    class SnippetViewSet(viewsets.ModelViewSet):
    
        def perform_create(self, serializer):
            serializer.save(owner=self.request.user)
    

  • 这三种方法很重要,具体取决于您的应用程序环境.但是我们什么时候需要使用每个 create()/perform_create() 函数呢?另一方面,我发现一些帐户为单个 post 请求调用了两个创建方法,ModelViewSetcreate() 和序列化程序的 create().

    These three approaches are important depending on your application environment. But when do we need to use each create() / perform_create() function? On the other hand, I found some accounts that two create methods were called for a single post request the ModelViewSet's create() and serializer's create().

    推荐答案

    1. 在保存和prod"之前,您可以使用 create(self,validated_data) 将任何额外的细节添加到对象中.就像 **validated_data 一样,将值添加到每个模型字段中.理想情况下,你想要做这种形式的刺激"仅在一个位置,因此 CommentSerializer 中的 create 方法是最佳位置.最重要的是,您可能还想在将您的帐户保存到您自己的数据库之前调用外部 apis 以在他们这边创建用户帐户.您应该将此create 函数与ModelViewSet 结合使用.始终思考 - 瘦视图,厚序列化器".

    1. You would use create(self, validated_data) to add any extra details into the object before saving AND "prod" values into each model field just like **validated_data does. Ideally speaking, you want to do this form of "prodding" only in ONE location so the create method in your CommentSerializer is the best place. On top of this, you might want to also call external apis to create user accounts on their side just before saving your accounts into your own database. You should use this create function in conjunction withModelViewSet. Always think - "Thin views, Thick serializers".

    示例:

    def create(self, validated_data):
        email = validated_data.get("email", None)
        validated.pop("email") 
        # Now you have a clean valid email string 
        # 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)
    

  • ModelViewSet 中的create(self, request, *args, **kwargs) 函数在CreateModelMixin 中定义ModelViewSet 的父类.CreateModelMixin 的主要功能如下:

  • The create(self, request, *args, **kwargs) function in the ModelViewSet is defined in the CreateModelMixin class which is the parent of ModelViewSet. CreateModelMixin's main functions are these:

    from rest_framework import status
    from rest_framework.response import Response
    
    
    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 函数负责在序列化程序上调用验证并生成正确的响应.这背后的美妙之处在于,您现在可以隔离您的应用程序逻辑,而不必担心平凡和重复的验证调用和处理响应输出:).这与序列化程序(您的特定应用程序逻辑可能驻留的位置)中的 create(self,validated_data) 结合使用效果非常好.

    As you can see, the above create function takes care of calling validation on your serializer and producing the correct response. The beauty behind this, is that you can now isolate your application logic and NOT concern yourself about the mundane and repetitive validation calls and handling response output :). This works quite well in conjuction with the create(self, validated_data) found in the serializer (where your specific application logic might reside).

    现在你可能会问,为什么我们有一个单独的 perform_create(self, serializer) 函数,只有一行代码!?!?嗯,这背后的主要原因是在调用 save 函数时允许自定义.您可能希望在调用 save (例如 serializer.save(owner=self.request.user) 之前提供额外的数据,如果我们没有的话)t 有 perform_create(self, serializer),你将不得不覆盖 create(self, request, *args, **kwargs) 而这只是违背了拥有的目的mixins 完成繁重而无聊的工作.

    Now you might ask, why do we have a separate perform_create(self, serializer) function with just one line of code!?!? Well, the main reason behind this is to allow customizeability when calling the save function. You might want to supply extra data before calling save (like serializer.save(owner=self.request.user) and if we didn't have perform_create(self, serializer), you would have to override the create(self, request, *args, **kwargs) and that just defeats the purpose of having mixins doing the heavy and boring work.

    这篇关于何时使用 Serializer 的 create() 和 ModelViewset 的 perform_create()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆