Serializer के create () और ModelViewset के create () perform_create () का उपयोग कब करें


102

मैं django-rest-frameworkएक मॉडल ऑब्जेक्ट के निर्माण के संबंध में दिए गए प्रलेखन को स्पष्ट करना चाहता हूं । अब तक मैंने पाया कि इस तरह की घटनाओं को संभालने के लिए 3 दृष्टिकोण हैं।

  1. धारावाहिक की create()विधि। यहाँ प्रलेखन है

    class CommentSerializer(serializers.Serializer):
    
        def create(self, validated_data):
            return Comment.objects.create(**validated_data)
    
  2. ModelViewset create()विधि। प्रलेखन

    class AccountViewSet(viewsets.ModelViewSet):
    
        queryset = Account.objects.all()
        serializer_class = AccountSerializer
        permission_classes = [IsAccountAdminOrReadOnly]
    
  3. ModelViewset perform_create()विधि। प्रलेखन

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

आपके एप्लिकेशन वातावरण के आधार पर ये तीन दृष्टिकोण महत्वपूर्ण हैं।

लेकिन हमें प्रत्येक create() / perform_create()फ़ंक्शन का उपयोग करने की आवश्यकता है क्या ?? दूसरी ओर मुझे कुछ खाते मिले कि दो साक्षात्कार विधियाँ एक ही पोस्ट अनुरोध के लिए बुलाई गई थीं जो कि मॉडल साक्षात्कारकर्ता create()और धारावाहिक की है create()

उम्मीद है कि कोई भी अपने कुछ ज्ञान को समझाने के लिए साझा करेगा और यह निश्चित रूप से मेरी विकास प्रक्रिया में बहुत सहायक होगा।

जवाबों:


131
  1. आप create(self, validated_data)किसी भी अतिरिक्त विवरण को सहेजने से पहले ऑब्जेक्ट में किसी भी अतिरिक्त विवरण को जोड़ने का उपयोग करेंगे और प्रत्येक मॉडल फ़ील्ड में "ठेस" मानों को जैसे **validated_dataकरते हैं। आदर्श रूप से, आप केवल एक स्थान पर "ठेस" के इस रूप को करना चाहते हैं ताकि createआपके लिए विधि CommentSerializerसबसे अच्छी जगह हो। इसके शीर्ष पर, आप अपने खातों को अपने डेटाबेस में सहेजने से ठीक पहले उपयोगकर्ता खाता बनाने के लिए बाह्य एपिस को भी कॉल कर सकते हैं। आपको इस createफ़ंक्शन का संयोजन के साथ उपयोग करना चाहिए ModelViewSet। हमेशा सोचें - "पतले विचार, मोटे धारावाहिक"।

उदाहरण:

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)
  1. इस create(self, request, *args, **kwargs)फ़ंक्शन को उस वर्ग ModelViewSetमें परिभाषित किया गया है, CreateModelMixinजिसके माता-पिता हैं ModelViewSetCreateModelMixinमुख्य कार्य ये हैं:

    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)धारावाहिक (जहां आपके विशिष्ट एप्लिकेशन तर्क निवास कर सकता है) में पाया के साथ संयोजन के रूप में काफी अच्छी तरह से काम करता है ।

  1. अब आप पूछ सकते हैं, हमारे पास perform_create(self, serializer)कोड की सिर्फ एक पंक्ति के साथ एक अलग फ़ंक्शन क्यों है ?!?! खैर, इसके पीछे मुख्य कारण saveफ़ंक्शन को कॉल करते समय कस्टमाइज़बिलिटी की अनुमति है। आप कॉल करने से पहले अतिरिक्त डेटा की आपूर्ति करना पसंद कर सकते हैं save (जैसेserializer.save(owner=self.request.user) और अगर हमारे पास नहीं था perform_create(self, serializer), तो आपको ओवरराइड करना होगा create(self, request, *args, **kwargs)और यह सिर्फ भारी और उबाऊ काम करने वाले मिक्सिंस के उद्देश्य को पराजित करता है।

उम्मीद है की यह मदद करेगा!


नमस्ते! अपने ज्ञान को साझा करने के लिए धन्यवाद! create(self, validated_data)धारावाहिक के बारे में , इसका मतलब है कि यह डेटा सत्यापन तर्क पर केंद्रित है? और अधिक से अधिक यह सही जवाब के लिए दिए गए serializer के डेटा को वापस करने में मदद कर सकता है?
Roel

1
इस बिंदु पर ऐसा नहीं है, आप पहले से ही अपनी सारी मान्यता पारित कर चुके हैं। मैं इस बारे में बात कर रहा हूं कि आप डेटाबेस में सहेजे जाने से पहले मान्य डेटा को कैसे अनुकूलित करना चाहते हैं। मैं अपने उत्तर में एक उदाहरण दूंगा।
अपूर्व कांसल

1
कोई चिंता नहीं - बस अधिक उदाहरण देने के लिए एक उदाहरण जोड़ा।
अपूर्व कांसल

1
हाँ, वह अंतिम पंक्ति है जो डेटाबेस में आपकी वस्तु को बचाएगी
अपूर्व कांसल

1
तो createधारावाहिक में कार्य केवल तभी कहा जाता है जब आप करते हैं serializer.save()। आपके create(self, request)फ़ंक्शन में ( AccountViewSet), आप बिलकुल भी कॉल नहीं कर रहे हैं serializer.save()और इसलिए, केवल उदाहरण निर्माण इस कॉल के साथ हो रहा है Account.objects.create_user(**serializer.validated_data):।
अपूर्व कांसल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.