7

मुझे कुछ समस्याएं आ रही हैं (पढ़ें: डीआरवाई & रखरखाव योग्य) स्थान डीजेगो में सत्यापन तर्क, अर्थात मॉडल, रूपों और डीआरएफ धारावाहिकों के बीच।डीजेगो डीआरवाई मॉडल/फॉर्म/सीरियलाइज़र प्रमाणीकरण

मैंने कई वर्षों से Django के साथ काम किया है और मॉडल, फॉर्म, और आरईएसटी एपीआई एंडपॉइंट सत्यापन को संभालने के लिए विभिन्न सम्मेलनों का पालन कर रहा हूं। मैंने समग्र डेटा अखंडता सुनिश्चित करने के लिए कई बदलावों की कोशिश की है, लेकिन मैंने हाल ही में एक ठोकर खाई है। यहाँ मैं क्या कई लेख के माध्यम से देखने के बाद की कोशिश की है की एक संक्षिप्त सूची है, अतः पोस्ट, और टिकट:

  1. मॉडल स्तर पर मान्यता; अर्थात्, मेरी सभी कस्टम बाधाओं को सुनिश्चित करना myModel.save() को myModel.clean() (साथ ही फील्ड-विशिष्ट और अद्वितीय एक साथ विधियों) को ओवरराइड करके कॉल करने से पहले मेल खाता है। ऐसा करने के लिए, मैंने myModel.full_clean() को myForm.clean() (फॉर्म के लिए - और व्यवस्थापक पैनल वास्तव में पहले से ही यह करता है) और mySerializer.validate() (डीआरएफ धारावाहिकों के लिए) विधियों में कहा गया था।

  2. फॉर्म और सीरिएलाइज़र स्तर पर सत्यापन, रखरखाव योग्य, डीआरवाई कोड के लिए एक साझा विधि को बुला रहा है।

  3. फॉर्म और सीरिएलाइज़र स्तर पर प्रमाणीकरण, प्रत्येक के लिए अधिकतम लचीलापन सुनिश्चित करने के लिए एक अलग विधि के साथ (यानी जब फॉर्म और एंडपॉइंट्स की अलग-अलग बाधाएं होती हैं)।

जब कोई रूप और धारावाहिकों की समान बाधाएं होती हैं, तो विधि मेरे लिए सबसे सहज महसूस करती है, लेकिन अभ्यास में थोड़ा गन्दा है; सबसे पहले, डेटा को स्वचालित रूप से फॉर्म या सीरिएलाइज़र द्वारा साफ और मान्य किया जाता है, फिर मॉडल इकाई को तत्काल चालू किया जाता है, और अधिक सत्यापन फिर से चलाया जाता है - जो थोड़ा पतला होता है और जटिल हो सकता है।

विधि तीन जो Django Rest Framework संस्करण 3.0 के रूप में अनुशंसा करता है; उन्होंने अपने model.save() हुक को हटा दिया और अपने आवेदन के उपयोगकर्ता के सामने वाले पहलुओं को सत्यापन छोड़ना पसंद करते हैं। यह मुझे कुछ समझ में आता है, क्योंकि Django के बेस model.save() कार्यान्वयन model.full_clean() को किसी भी तरह से कॉल नहीं करता है।

तो, विधि दो मेरे लिए सबसे अच्छा समग्र सामान्य परिणाम प्रतीत होता है; सत्यापन एक विशिष्ट स्थान पर रहता है - मॉडल को कभी भी छुआ जाने से पहले - और साझा सत्यापन तर्क के कारण कोडबेस कम अव्यवस्थित/अधिक DRY है।

दुर्भाग्यवश, मुझे जो परेशानी आई है, वह है जो Django Rest Framework के serializers को सहयोग करने के लिए है। सभी तीन दृष्टिकोण रूपों के लिए अच्छी तरह से काम करते हैं, और वास्तव में अधिकांश HTTP विधियों के लिए अच्छी तरह से काम करते हैं (विशेष रूप से जब इकाई निर्माण के लिए पोस्ट करते हैं) - लेकिन मौजूदा इकाई (पुट, पैच) को अद्यतन करते समय कोई भी अच्छी तरह से खेलना प्रतीत नहीं होता है।

लंबी कहानी छोटी, यह अधूरा होने पर इनकमिंग डेटा को मान्य करना मुश्किल साबित हुआ है (लेकिन अन्यथा वैध - अक्सर पैच के मामले में)। अनुरोध डेटा में केवल कुछ फ़ील्ड हो सकते हैं - जिनमें अलग/नई जानकारी होती है - और मॉडल उदाहरण की मौजूदा जानकारी अन्य सभी क्षेत्रों के लिए बनाए रखा जाता है। वास्तव में, DRF issue #4306 पूरी तरह से इस विशेष चुनौती को बताता है।

मैंने विचारधारा स्तर पर चल रहे कस्टम मॉडल सत्यापन को भी माना है (serializer.validated_data populated और serializer.instance मौजूद है, लेकिन serializer.save() कहा जाता है), लेकिन मैं अभी भी आने के लिए संघर्ष कर रहा हूं अद्यतनों को संभालने की जटिलताओं के कारण एक स्वच्छ, सामान्यीकृत दृष्टिकोण के साथ।

टी एल; डॉ Django बाकी फ्रेमवर्क विशेष रूप से है कि मौजूदा मॉडल डेटा और आने वाली अनुरोध डेटा का एक मिश्रण पर भरोसा आंशिक अद्यतन के लिए, यह थोड़ा कठिन एक स्पष्ट जगह में स्वच्छ, पोषणीय मान्यता तर्क लिखने के लिए बनाता है।

मुझे कुछ Django गुरुों को काम करने के लिए जो कुछ मिला है उस पर वजन करना अच्छा लगेगा, क्योंकि मुझे कोई सुविधाजनक समाधान नहीं दिख रहा है।

धन्यवाद।

+0

क्या आपको अपने उत्तर के लिए समाधान मिला? – Infernion

उत्तर

0

बस एहसास हुआ कि मैंने कभी भी इस समाधान पर अपना समाधान पोस्ट नहीं किया है। मैं बचत से पहले हमेशा सत्यापन चलाने के लिए एक मॉडल मिश्रण लिखना समाप्त कर दिया; यह थोड़ा असुविधाजनक है क्योंकि प्रमाणीकरण तकनीकी रूप से Django के रूपों में दो बार चलाया जाएगा (यानी व्यवस्थापक पैनल में), लेकिन यह मुझे गारंटी की गारंटी देता है कि प्रमाणीकरण चलाया जाता है - चाहे किसी मॉडल को सहेजने के बावजूद। मैं आम तौर पर Django के रूपों का उपयोग नहीं करता, इसलिए इसका मेरे अनुप्रयोगों पर अधिक प्रभाव नहीं पड़ता है।

class ValidatesOnSaveModelMixin: 
    """ ValidatesOnSaveModelMixin 
    A mixin that ensures valid model state prior to saving. 
    """ 
    def save(self, **kwargs): 
     self.full_clean() 
     super(ValidatesOnSaveModelMixin, self).save(**kwargs) 

यहाँ कैसे आप इसका उपयोग है:

यहां एक त्वरित टुकड़ा है कि चाल करता है

class ImportantModel(ValidatesOnSaveModelMixin, models.Model): 
    """ Will always ensure its fields pass validation prior to saving. """ 

वहाँ एक महत्वपूर्ण चेतावनी है: Django के डायरेक्ट-टू-डेटाबेस के किसी भी संचालन (यानी ImportantModel.objects.update()) मॉडल की save() विधि को कॉल न करें, और इसलिए मान्य नहीं किया जाएगा। इसके बारे में बहुत कुछ नहीं है, क्योंकि ये विधियां वास्तव में डेटाबेस कॉल का एक गुच्छा छोड़कर प्रदर्शन को अनुकूलित करने के बारे में हैं - इसलिए यदि आप उनका उपयोग करते हैं तो बस उनके प्रभाव से अवगत रहें।

1

मैं मानता हूं, मॉडल/धारावाहिक/सत्यापन के बीच का लिंक टूटा हुआ है।

सबसे अच्छा सूखी समाधान मैंने पाया मॉडल में सत्यापन रखने के लिए, खेतों पर निर्दिष्ट प्रमाणकों के साथ, तो अगर clean() अधिरोहित में की जरूरत है, मॉडल के स्तर का सत्यापन है।

फिर धारावाहिक में, ओवरराइड मान्य करें और मॉडल clean() उदा। MySerializer में:

def validate(self, data): 
    instance = FooModel(**data) 
    instance.clean() 
    return data 

यह अच्छा नहीं है, लेकिन मैं serializer और मॉडल में 2 स्तरीय मान्यता को यह पसंद करते हैं।

संबंधित मुद्दे