2012-10-23 16 views
23

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

from django.db import models 
from django.core import validators 
from django.core exceptions import ValidationError 


def validate_gender(value): 
    """ Custom validator """ 
    if not value in ('m', 'f', 'M', 'F'): 
     raise ValidationError(u'%s is not a valid value for gender.' % value) 


class Person(models.Model): 
    name = models.CharField(max_length=128) 
    age = models.IntegerField() 
    gender = models.CharField(maxlength=1, validators=[validate_gender]) 

    def save(self, *args, **kwargs): 
     """ Override Person's save """ 
     self.full_clean(exclude=None) 
     super(Person, self).save(*args, **kwargs) 

यहाँ मेरी सवाल कर रहे हैं:

  1. मैं एक कस्टम मान्यता समारोह बनाना चाहिए, एक सत्यापनकर्ता के रूप में यह निर्दिष्ट करते हैं, और उसके बाद व्यक्ति की सेव (ओवरराइड) समारोह के रूप में मैं यहाँ मेरी वर्तमान दृष्टिकोण है ऊपर किया है? (वैसे, मुझे पता है कि मैं 'विकल्प' फ़ील्ड विकल्प का उपयोग करके अपने लिंग विकल्पों को मान्य कर सकता हूं लेकिन मैंने चित्रण के उद्देश्य के लिए 'validate_gender' बनाया है)।

  2. मैं वास्तव में अपने डेटा की अखंडता को सुनिश्चित करना चाहते हैं हैं, तो मैं केवल मॉडल परत पर परीक्षण के लिए Django इकाई परीक्षण लेकिन यह भी बराबर डेटाबेस स्तरीय इकाई परीक्षण अजगर/Psycopg का उपयोग कर लिख नहीं करना चाहिए? मैंने देखा है कि Django यूनिट परीक्षण, जो ValidationErrors को बढ़ाता है, डेटाबेस की एक प्रति का उपयोग कर डेटाबेस स्कीमा की मॉडल की समझ का परीक्षण करता है। यहां तक ​​कि अगर मैं माइग्रेशन के लिए दक्षिण का उपयोग करना चाहता था, तो भी किसी भी डेटाबेस-स्तरीय बाधाओं को सीमित किया जाता है जो Django एक पोस्टग्रेस बाधा में समझ और अनुवाद कर सकता है। अगर मुझे एक कस्टम बाधा की आवश्यकता है जो Django दोहराना नहीं कर सकता है, तो संभवतः मैं अपने डेटाबेस में डेटा दर्ज कर सकता हूं जो उस बाधा का उल्लंघन करता है यदि मैं सीधे psql टर्मिनल के माध्यम से डेटाबेस के साथ बातचीत कर रहा हूं।

धन्यवाद!

+0

मुझे यकीन नहीं है कि इस विषय पर आपके पिछले प्रश्नों के लिए प्रश्न 1 अलग कैसे है। ध्यान दें कि यह अभी भी ओआरएम का उपयोग करके अमान्य डेटा डालने से नहीं रोकता है। 'Person.objects.update (लिंग =' ए ') पर विचार करें। – Alasdair

+1

आप सही हैं कि मेरे पिछले प्रश्न में मैंने एक कस्टम सत्यापनकर्ता फ़ंक्शन शामिल नहीं किया जैसा मैंने यहां किया था। .update के बारे में आपके अन्य अवलोकन के रूप में, मुझे लगता है कि अब मुझे एक अतिरिक्त समस्या है जो मेरे भ्रम में जोड़ती है।मैं वास्तव में यह समझने के लिए संघर्ष कर रहा हूं कि ऐसा करने का सही तरीका क्या है। जबकि Django दस्तावेज़ बहुत अच्छे हैं, आईएमएचओ, वे स्निपेट्स और "हैंड-वेविंग" पर लंबे समय तक हैं लेकिन पूर्ण उदाहरणों पर कम है जो इस समस्या को हल करने के लिए सही तरीके से समझने की तरह "newb" की मदद करेंगे। दुर्भाग्यवश, मैं अकेले काम करता हूं और इसके साथ चर्चा करने के लिए अधिक अनुभवी डेवलपर्स नहीं हैं। – William

उत्तर

16

जब मैंने पहली बार Django के साथ शुरू किया तो मुझे ओआरएम की एक समान गलतफहमी थी।

1) नहीं, save के अंदर न रखें। ModelForm.is_valid() स्पष्ट Model.full_clean फोन नहीं होगा, लेकिन Model.full_clean के रूप में ठीक उसी जांच निष्पादित करेगा): टिप्पणी - या तो

ए) एक ModelForm (जो सभी एक ही सत्यापन होने के लिए कारण होगा का उपयोग करें। उदाहरण:

class PersonForm(forms.ModelForm): 
    class Meta: 
     model = Person 

def add_person(request): 
    if request.method == 'POST': 
     form = PersonForm(request.POST, request.FILES) 
     if form.is_valid(): # Performs your validation, including ``validate_gender`` 
      person = form.save() 
      return redirect('some-other-view') 
    else: 
     form = PersonForm() 
     # ... return response with ``form`` in the context for rendering in a template 

यह भी ध्यान रखें, रूपों केवल विचारों कि उन्हें टेम्पलेट्स में प्रस्तुत में इस्तेमाल के लिए नहीं कर रहे हैं - वे एक API, आदि form.is_valid() चल रहा है और त्रुटियों मिलने के बाद सहित उपयोग की किसी भी प्रकार के लिए शानदार हैं, आपके पास form.errors होगा जो एक शब्दकोश है जिसमें फॉर्म में सभी त्रुटियां हैं, जिनमें '__all__' नामक कुंजी शामिल है जिसमें गैर-फील्ड त्रुटियां होंगी।

बी) किसी फॉर्म का उपयोग करने के बजाय बस अपने दृश्य (या अन्य लॉजिकल एप्लिकेशन लेयर) में model_instance.full_clean() का उपयोग करें, लेकिन फ़ॉर्म इसके लिए एक अच्छा अमूर्त है।

2) मेरे पास वास्तव में कोई समाधान नहीं है, लेकिन मैंने बड़ी परियोजनाओं में भी ऐसी समस्या में भाग नहीं लिया है (वर्तमान परियोजना में मैं अपनी कंपनी के साथ काम करता हूं जिसमें 146 टेबल हैं) और मैं नहीं करता संदेह है कि यह आपके मामले में भी चिंता का विषय होगा।

+2

क्या आप कह रहे हैं कि मुझे अपने डेटा मॉडल को सत्यापित करने के लिए एक फॉर्म या मॉडल फॉर्म का उपयोग करना चाहिए, भले ही मैं वास्तव में किसी उपयोगकर्ता को वास्तविक टेम्पलेट फ़ॉर्म में मॉडल ऑब्जेक्ट प्रस्तुत नहीं कर रहा हूं? धन्यवाद। – William

+1

@RobertF। - यह सही है। मॉडल मॉडल के लिए 'मॉडलफॉर्म' क्लास एक सभ्य अमूर्त है, चाहे आप टेम्पलेट में फॉर्म प्रदर्शित करने का इरादा नहीं रखते हैं, भले ही उदाहरण अपडेट या निर्माण कर रहे हों। – orokusaki

+1

आपने या तो ए कहा था) ऐसा करें, और विकल्प बी क्या है? – rgenito

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