Django

2012-01-07 5 views
38

में मॉडल की सहेजने की विधि में एक सत्यापन त्रुटि बढ़ाएं मुझे यकीन नहीं है कि किसी मॉडल की सहेजने विधि में सत्यापन त्रुटि को सही तरीके से कैसे उठाया जाए और उपयोगकर्ता को एक स्पष्ट संदेश वापस भेज दें।Django

असल में मैं जानना चाहता हूँ कि कैसे के प्रत्येक भाग "अगर" खत्म होना चाहिए, वह है जहां मैं त्रुटि बढ़ाने के लिए चाहते हैं और एक जहाँ यह वास्तव में सहेजता है:

def save(self, *args, **kwargs): 
    if not good_enough_to_be_saved: 
     raise ValidationError 
    else: 
     super(Model, self).save(*args, **kwargs) 

तो मैं जानना चाहता हूँ एक सत्यापन त्रुटि भेजने के लिए क्या करना है जो उपयोगकर्ता को बिल्कुल सही कहता है कि एक Django स्वचालित रूप से वापस लौटाता है, उदाहरण के लिए यदि कोई मान अद्वितीय नहीं है। मैं एक (मॉडलफॉर्म) का उपयोग कर रहा हूं और मॉडल से सब कुछ ट्यून कर रहा हूं।

उत्तर

32

अधिकांश Django विचार उदा। Django व्यवस्थापक सहेजने की विधि में सत्यापन त्रुटि को संभालने में सक्षम नहीं होगा, इसलिए आपके उपयोगकर्ताओं को 500 त्रुटियां मिलेंगी।

आपको मॉडल फॉर्म या मॉडल पर सत्यापन करना चाहिए, और वहां ValidationError उठाएं। फिर केवल save() पर कॉल करें यदि मॉडल फॉर्म डेटा 'सहेजने के लिए पर्याप्त' है।

+0

आप सही मैं में मेरी मान्यता पर आ जाएगा रहे हैं फॉर्म, यह आसान तरीका है। मुझे बस मॉडल में सबकुछ रखने का विचार पसंद आया। – Bastian

+8

@bastian, मुझे मॉडल में सबकुछ भी पसंद आया। जब आप एक नया फॉर्म लिखते हैं तो व्यवसाय नियम को भूलना आसान होता है, लेकिन यदि व्यापार नियम मॉडल में नहीं हैं। इस कारण से मैंने फॉर्मों से मॉडल में सत्यापन को स्थानांतरित कर दिया है जैसा कि मैंने अपनी पोस्ट में बताया है। यदि यह अस्तित्व में है तो इसे और अधिक सुरुचिपूर्ण तरीके से करने के लिए नए तरीकों के बारे में जानने के लिए मैं खुली हूं। किसी भी मामले में मैं फॉर्म पर सत्यापन कोड लिखने से बचता हूं। – danihp

+6

वैधता का उपयोग करके या 'स्वच्छ()' विधि लिखकर अपने मॉडल में सत्यापन करना ठीक है। मैं बस इतना कह रहा था कि 'सेव()' विधि सही जगह नहीं है। [मान्य वस्तुओं] पर दस्तावेज़ों पर एक नज़र डालें (https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects)। – Alasdair

22

Bastian, मैं तुम्हें करने के लिए अपने कोड templating समझाते हैं, मुझे आशा है कि आप में मदद करता है:

django 1.2 it is able to write validation code on model के बाद से। जब हम मॉडलफॉर्म के साथ काम करते हैं, example.full_clean() को फॉर्म सत्यापन पर बुलाया जाता है।

प्रत्येक मॉडल में मैं एक कस्टम समारोह के साथ clean() विधि के ऊपर लिख (इस विधि को स्वचालित रूप से modelform सत्यापन पर full_clean से कहा जाता है()):

from django.db import models 

class Issue(models.Model): 
    .... 
    def clean(self): 
     rules.Issue_clean(self) #<-- custom function invocation 

from issues import rules 
rules.connect() 

फिर rules.py फ़ाइल में मैं मास्टर ऑफ बिजनेस नियमों लिखें। इसके अलावा मैं अपने कस्टम कार्य करने के लिए pre_save() कनेक्ट गलत राज्य के साथ एक मॉडल को बचाने को रोकने के लिए:

से issues.models आयात जारी करना

def connect():  
    from django.db.models.signals import post_save, pre_save, pre_delete 
    #issues 
    pre_save.connect(Issue_pre_save, sender = Incidencia) 
    post_save.connect(Issue_post_save, sender = Incidencia) 
    pre_delete.connect(Issue_pre_delete, sender= Incidencia) 

def Incidencia_clean(instance): #<-- custom function 
    import datetime as dt  
    errors = {} 

    #dia i hora sempre informats  
    if not instance.dia_incidencia: #<-- business rules 
     errors.setdefault('dia_incidencia',[]).append(u'Data missing: ...') 

    #dia i hora sempre informats  
    if not instance.franja_incidencia: 
     errors.setdefault('franja_incidencia',[]).append(u'Falten Dades: ...') 

    #Només es poden posar incidències més ennlà de 7 dies 
    if instance.dia_incidencia < (dt.date.today() + dt.timedelta(days = -7)): 
     errors.setdefault('dia_incidencia 1',[]).append(u'''blah blah error desc)''') 

    #No incidències al futur. 
    if instance.getDate() > datetime.now(): 
     errors.setdefault('dia_incidencia 2',[]).append(u'''Encara no pots ....''') 
    ... 

    if len(errors) > 0: 
     raise ValidationError(errors) #<-- raising errors 

def Issue_pre_save(sender, instance, **kwargs): 
    instance.clean()  #<-- custom function invocation 

फिर

, modelform कॉल मॉडल के स्वच्छ विधि और एक सही राज्य के लिए मेरे custon समारोह की जांच या मॉडल फॉर्म द्वारा प्रबंधित एक त्रुटि उठाओ।

आदेश फार्म पर त्रुटियों को दिखाने के लिए है, तो आप प्रपत्र टेम्पलेट पर इस शामिल करना चाहिए:

{% if form.non_field_errors %} 
     {% for error in form.non_field_errors %} 
     {{error}} 
     {% endfor %} 
{% endif %} 

कारण यह है कि मॉडल मान्यता मिली त्रुटियाँ आरा non_field_errors शब्दकोश त्रुटि प्रविष्टि से आबद्ध है।

जब आप को बचाने या एक फार्म के बाहर एक मॉडल आप याद रखना चाहिए कि एक त्रुटि उठाया जा सकता है हटा दें:

try: 
     #provoco els errors per mostrar-los igualment al formulari. 
     issue.clean() 
    except ValidationError, e: 
     form._errors = {} 
     for _, v in e.message_dict.items(): 
      form._errors.setdefault(NON_FIELD_ERRORS, []).extend( v ) 
:

try: 
    issue.delete() 
except ValidationError, e: 
    import itertools 
    errors = list(itertools.chain(*e.message_dict.values())) 

इसके अलावा, आप कोई modelforms पर एक फार्म शब्दकोश में त्रुटियों जोड़ सकते हैं

याद रखें कि यह कोड save() विधि पर निष्पादित नहीं है: ध्यान दें कि जब आप अपने मॉडल की सेव() विधि को कॉल करते हैं, न ही मॉडलफॉर्म सत्यापन के परिणामस्वरूप full_clean() स्वचालित रूप से नहीं कहा जाएगा।उसके बाद, आप कोई modelforms पर एक फार्म शब्दकोश में त्रुटियों जोड़ सकते हैं:

try: 
     #provoco els errors per mostrar-los igualment al formulari. 
     issue.clean() 
    except ValidationError, e: 
     form._errors = {} 
     for _, v in e.message_dict.items(): 
      form._errors.setdefault(NON_FIELD_ERRORS, []).extend( v ) 
+1

आपकी लंबी व्याख्या के लिए मोल्टेस ग्रैसीज। मैं कुछ स्वचालित, Djangoish की तलाश में था। आपका उदाहरण अन्य परिस्थितियों के लिए मुझे रूचि दे सकता है लेकिन जो मैं अब लिख रहा हूं वह केवल 1 लाइन सत्यापन है इसलिए मैं यहां पूरी चीज को लागू नहीं करूंगा। – Bastian

+3

आपका स्वागत है। कुछ दिन कैटलोनिया जाने के लिए मत भूलना :) – danihp

+7

मैं बार्सिलोना में रहता हूं :) – Bastian

1

रूप में अच्छी तरह ValidationError आयात करने के लिए सुनिश्चित हो

from django.core.exceptions import ValidationError 
-1
def clean(self): 
    raise ValidationError("Validation Error") 

def save(self, *args, **kwargs): 
    if some condition: 
     #do something here 
    else: 
     self.full_clean() 
    super(ClassName, self).save(*args, **kwargs) 
+1

पोस्टिंग कोड पर्याप्त नहीं है, आपको कुछ स्पष्टीकरण देना चाहिए। – Ivan

+0

आप फ़ंक्शन सहेजने में full_clean() विधि को कॉल कर सकते हैं, यह Django == 1.11 में ठीक काम करता है, मुझे पुराने संस्करण के बारे में निश्चित नहीं है। –

+0

इसे बेहतर बनाने के लिए इस जानकारी को अपने उत्तर में जोड़ें। – Ivan