2010-08-26 17 views
18

मॉडल के मौजूदा ऑब्जेक्ट्स से किसी फ़ील्ड को ले जाने के लिए मैं डिफ़ॉल्ट मान कैसे बना सकता हूं?Django: स्व मॉडल के उदाहरणों से फ़ील्ड का डिफ़ॉल्ट मान

मैं इन की कोशिश की और यह काम किया नहीं किया:

1)

class ModelA(models.Model): 
    fieldA = models.CharField(default=self.get_previous()) 

    def get_previous(self): 
     return ModelA.objects.all()[0].fieldA 

NameError: name 'self' is not defined

2)

class ModelA(models.Model): 
    fieldA = models.CharField(default=ModelA.get_previous()) 

    @staticmethod 
    def get_previous(): 
     return ModelA.objects.all()[0].fieldA 

NameError: name 'ModelA' is not defined

3)

class ModelA(models.Model): 
    fieldA = models.CharField(default=get_previous()) 

def get_previous(): 
    return ModelA.objects.all()[0].fieldA 

NameError: global name 'get_previous' is not defined

4)

def get_previous(): 
    return ModelA.objects.all()[0].fieldA 

class ModelA(models.Model): 
    fieldA = models.CharField(default=get_previous()) 

NameError: global name 'ModelA' is not defined

मैं यह स्पष्ट है क्यों 3) और 4) काम नहीं करेगा। मैं कल्पना कर सकता हूं कि क्यों 1) काम नहीं करेगा - ऐसा लगता है कि वर्ग की प्रस्तुतियां उदाहरण (यानी स्वयं) का संदर्भ नहीं दे सकती हैं। मैं कल्पना कर सकता हूं कि क्यों 2) काम नहीं करेगा - स्पष्ट रूप से मॉडलए का कोई संदर्भ नहीं है जब तक दुभाषिया पूरी कक्षा में नहीं जायेगा।

तो मुझे यह कैसे संपर्क करना चाहिए?

उत्तर

16

अपने उदाहरणों में, आपको कॉल ऑपरेटर () को हटाने की आवश्यकता है।

वर्तमान में बयान पहले पढ़ने-विश्लेषण चक्र पर तुरंत निष्पादित किया जाता है। इसके बजाय प्रतीक नाम निर्दिष्ट करके, Django क्लास एक फ़ंक्शन पॉइंटर प्राप्त करता है जो इसे वास्तव में डिफ़ॉल्ट मान की आवश्यकता होने पर निष्पादित करेगा।

उदाहरण बन जाता है:

def get_previous(): 
    return ModelA.objects.all()[0].fieldA 

class ModelA(models.Model): 
    fieldA = models.CharField(default=get_previous) 

आप क्षेत्रों का एक बहुत के लिए यह करने के लिए, save समारोह overridding पर विचार करें, ताकि आप केवल सिर्फ एक बार डेटाबेस से पिछले वस्तु लाने के लिए है जा रहे हैं।

+1

अच्छा बिंदु! मेरे मामले में हालांकि मेरे पास डिफ़ॉल्ट मान पाने के लिए कई फ़ील्ड हैं इसलिए मुझे प्रत्येक के लिए अलग-अलग फ़ंक्शन की आवश्यकता होगी। (लेकिन मैं इसे सामान्य बनाने के लिए लैम्ब्डा का उपयोग करने पर विचार करूंगा, 'लैम्ब्डा: get_default (' field_name ')') – grucha

+1

समतुल्य रूप से, आपको 'डिफ़ॉल्ट = lambda: ModelA.objects.all() [0] करने में सक्षम होना चाहिए। fieldA'। –

+1

ध्यान रखें कि डिफ़ॉल्ट रूप से लैम्ब्डा फ़ंक्शन का उपयोग करके माइग्रेशन के साथ गड़बड़ी होगी क्योंकि लैम्ब्डा फ़ंक्शंस को क्रमबद्ध नहीं किया जा सकता है। – Ironbeard

3

तुम सिर्फ उत्पादन डिफ़ॉल्ट मान चाहते हैं, ओवरराइड __getattr__() विधि इस तरह: वस्तु से

class ModelA(models.Model): 
    # your fields 
    def __getattr__(self, name): 
    if(name == 'fieldA' and !self.fieldA): 
     return self.get_previous() 
    else: 
     return super(ModelA, self).__getattr__(name) 

सहेजा जा रहा है डिफ़ॉल्ट मान थोड़ा difficultier हो जाएगा। पहला समाधान जो मेरे दिमाग में आता है, override save() method (मुझे विश्वास है कि सरल समाधान है)

3

विकल्प 1: Use model forms। ये मॉडल के आधार पर रूप हैं, कि आप आसानी से अपने मानों को विशिष्ट उदाहरण से मानों के साथ पॉप्युलेट कर सकते हैं। यह विकल्प अच्छा है यदि आप डिफॉल्ट मान चाहते हैं कि उपयोगकर्ता को फॉर्म में कुछ दिखाना चाहिए, जाहिर है।

विकल्प 2: Override the model's save method, और वहां चेक को कोड करें - यदि फ़ील्ड ए कोई नहीं है, तो इसमें कुछ मूल्य डालें। यह विकल्प बेहतर है यदि आप डेटा लेयर पर काम करने के लिए डिफ़ॉल्ट मान चाहते हैं, न केवल फॉर्म डिफ़ॉल्ट मान (यानी, अन्य तरीकों से बनाए गए उदाहरणों के लिए)।

+0

मेरा बिंदु उपयोगकर्ता को डिफ़ॉल्ट मान दिखाना है, यदि कोई मूल्य नहीं है तो इसे सहेजने के लिए नहीं, इसलिए आपके उत्तर का विकल्प_1 अच्छा दिखता है। हालांकि मुझे vdboor का जवाब अधिक पसंद है क्योंकि यह पाइथन स्तर है और काफी django-विशिष्ट नहीं है। Djangonauts, अगर मैं गलत तरीके से जा रहा हूँ मुझे सही करें ;-) – grucha

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