2011-05-23 11 views
13

के लिए मोंगोइंजिन दस्तावेज़ वर्ग विधियों का उपयोग करके मैं वर्तमान में मोंगोइंजिन "ऑब्जेक्ट दस्तावेज़ मैपर" की संभावनाओं की खोज कर रहा हूं। वर्तमान में मुझे यह स्पष्ट नहीं है कि मैं अपने सत्यापन और ऑब्जेक्ट निर्माण तर्क को दस्तावेज़ ऑब्जेक्ट्स में कितनी हद तक ले जा सकता हूं।कस्टम सत्यापन और प्री-सेव हुक

मैं धारणा है कि यह एक समस्या नहीं होनी चाहिए है, लेकिन मैं

  • कस्टम सत्यापन कार्यों कि स्वचालित रूप से बचाने पर कहा जाता है के रूप में उदाहरण/चेतावनियां/सबसे अच्छा मुद्दों के बारे में प्रथाओं का एक बहुत नहीं लग रहा हूँ () मूल्यांकन करने के लिए कि फ़ील्ड सामग्री वैध हैं या नहीं;
  • किसी क्षेत्र की सामग्री के हैश पर आधारित() पर पहचानकर्ता की स्वचालित पीढ़ी;

मैं मैं बचाने() विधि ओवरराइड करने के लिए, ताकि मैं अपने कस्टम तर्क कॉल कर सकते हैं की जरूरत है, लेकिन उदाहरण की कमी मुझे विश्वास है कि एक गलत दृष्टिकोण हो सकता है कि ...

MongoEngine का उपयोग कर उच्च गुणवत्ता वाले कोडबेस के लिए कोई भी उदाहरण, या संदर्भ स्वागत है।

उत्तर

14

आप सामान्य चेतावनी के साथ save() ओवरराइड कर सकते हैं, जिसे आपको मूल वर्ग की विधि को कॉल करना होगा।

class MyDocument(mongoengine.Document): 

    def save(self, *args, **kwargs): 
     for hook in self._pre_save_hooks: 
      # the callable can raise an exception if 
      # it determines that it is inappropriate 
      # to save this instance; or it can modify 
      # the instance before it is saved 
      hook(self): 

     super(MyDocument, self).save(*args, **kwargs) 

इसके बाद आप किसी दिए गए मॉडल वर्ग के लिए हुक को परिभाषित कर सकते हैं:

आप पाते हैं कि आप अपने सभी मॉडलों के लिए मान्यता हुक जोड़ना चाहते हैं, तो आप Document कुछ तरह के एक कस्टम बच्चे वर्ग बनाने पर विचार हो सकता एक काफी प्राकृतिक तरीके:

class SomeModel(MyDocument): 
    # fields... 

    _pre_save_hooks = [ 
     some_callable, 
     another_callable 
    ] 
7

तुम भी दस्तावेज़ पर सत्यापित करें विधि रद्द कर सकते थे, लेकिन आप सुपर क्लास दस्तावेज़ त्रुटियों निगल करने के लिए ताकि आप उन्हें करने के लिए अपने त्रुटियों जोड़ सकते हैं आवश्यकता होगी

यह दुर्भाग्य से मोंगोइंजिन में आंतरिक कार्यान्वयन विवरणों पर निर्भर करता है, इसलिए कौन जानता है कि यह भविष्य में टूट जाएगा या नहीं।

class MyDoc(Document): 
    def validate(self): 
     errors = {} 
     try: 
      super(MyDoc, self).validate() 
     except ValidationError as e: 
      errors = e.errors 

     # Your custom validation here... 
     # Unfortunately this might swallow any other errors on 'myfield' 
     if self.something_is_wrong(): 
      errors['myfield'] = ValidationError("this field is wrong!", field_name='myfield') 

     if errors: 
      raise ValidationError('ValidationError', errors=errors) 

इसके अलावा, वहाँ (जैसे पहचानकर्ता पीढ़ी आप प्रश्न में उल्लेख किया) हुक के अन्य प्रकार से निपटने के लिए MongoEngine में उचित संकेत समर्थन अब है।

http://mongoengine.readthedocs.io/en/latest/guide/signals.html

+0

लिंक टूटा हुआ है, सही एक है http://mongoengine.readthedocs.org/en/latest/guide/signals.html इसके बगल में मैं इस दृष्टिकोण को नहीं जाने का सुझाव दूंगा यदि समस्या को हल करने के अन्य तरीके हैं (जैसा कि अन्य उत्तरों में सुझाया गया है)। मेरी राय में लाइब्रेरी के अपवाद प्रवाह को अवरुद्ध करते समय आपके कोड की रखरखाव कम हो जाएगी। – karfau

20

कस्टम सत्यापन अब implementing the clean() method on a model द्वारा किया जाना चाहिए।

class Essay(Document): 
    status = StringField(choices=('Published', 'Draft'), required=True) 
    pub_date = DateTimeField() 

    def clean(self): 
     """ 
     Ensures that only published essays have a `pub_date` and 
     automatically sets the pub_date if published and not set. 
     """ 
     if self.status == 'Draft' and self.pub_date is not None: 
      msg = 'Draft entries should not have a publication date.' 
      raise ValidationError(msg) 

     # Set the pub_date for published items if not set. 
     if self.status == 'Published' and self.pub_date is None: 
      self.pub_date = datetime.now() 

संपादित करें: जिसके अनुसार, आप clean() के रूप में यह मॉडल नियम अपने मॉडल परिभाषा में सेट के आधार पर मान्य करने से पहले validate() से कहा जाता है का उपयोग कर सावधान रहना होगा।

+2

मेरी राय में सबसे अच्छा तरीका। MongoEngine स्रोत कोड में 'क्लीन()' फ़ंक्शन में टिप्पणी भी देखें: https://github.com/MongoEngine/mongoengine/blob/master/mongoengine/base/document।पीई # एल 230 - सत्यापन पूर्ण होने से पहले दस्तावेज़ स्तर डेटा सफाई करने के लिए हुक। इस विधि द्वारा उठाए गए किसी भी सत्यापन त्रुटि को किसी विशेष फ़ील्ड से संबद्ध नहीं किया जाएगा; इसमें फ़ील्ड के साथ NON_FIELD_ERRORS द्वारा परिभाषित फ़ील्ड के साथ एक विशेष-केस एसोसिएशन होगा। इसलिए यदि आप फ़ील्ड-स्तरीय सत्यापन चाहते हैं तो मुझे लगता है कि आपको एक कस्टम फ़ील्ड लिखना चाहिए। – rednaw

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