2016-12-12 81 views
20

我想澄清關於創建模型對象的給定文檔django-rest-framework。到目前爲止,我發現有3種方法來處理這類事件。何時使用序列化程序的create()和ModelViewset的create()perform_create()

  1. The Serializer's create() method。這裏是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) 
    

這種三種方法取決於你的應用環境是非常重要的。

但是當我們需要使用每個create()/perform_create()函數??。另一方面,我發現一個帳戶,兩個創建方法被稱爲一個單一的postview請求modelviewset的create()和序列化的create()

希望任何人都可以分享他們的一些知識來解釋,這對我的開發過程肯定很有幫助。

回答

23
  1. 你會使用create(self, validated_data)節約型和「刺」的價值觀爲每個型號場就像**validated_data做之前添加任何額外的細節到對象。理想情況下,您只想在一個位置使用這種「刺激」形式,因此CommentSerializer中的create方法是最好的選擇。除此之外,您還可以在將帳戶保存到自己的數據庫之前,調用外部apis來創建用戶帳戶。您應該將此create函數與ModelViewSet結合使用。總是想 - 「薄視圖,厚序列化器」。

實施例:

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) 
  • ModelViewSetcreate(self, request, *args, **kwargs)功能在CreateModelMixin類,這是的ModelViewSet父定義。 CreateModelMixin的主要功能是這些:

    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)(您的特定應用程序邏輯可能駐留的地方)很好地結合使用。

    1. 現在你可能會問,爲什麼我們只有一行代碼就有單獨的perform_create(self, serializer)函數!?!?那麼,背後的主要原因是在調用save函數時允許自定義。您可能需要調用save(如serializer.save(owner=self.request.user),如果我們沒有perform_create(self, serializer),你就必須重寫create(self, request, *args, **kwargs)而只是違背了混入做繁重而枯燥的工作的目的之前,提供額外的數據。

    希望這有助於!

    +0

    你好!謝謝你的分享你的知識!關於'創建(個體經營,validated_data)'在串行器,這意味着它的重點是數據驗證邏輯?多了,它可以幫助迴歸給定的序列化程序的數據返回到響應權限? –

    +0

    沒有,所以在這一點上,你已經通過了所有的validat離子。我正在討論在將數據保存到數據庫之前,如何定製已驗證的數據。我會以我的答案爲例。 –

    +0

    哦,是的,我明白了 –

    相關問題