2009-05-29 9 views
27

कहते हैं कि मैं एक मॉडल फू कि SuperFoo से इनहेरिट करते हैं SuperFoo का नाम फ़ील्ड। क्या मैं? यदि नहीं, तो टेम्पलेट में प्रदर्शित होने के लिए मॉडल फॉर्म परिभाषा के अंदर एक लेबल सेट करने का सबसे अच्छा विकल्प है?कैसे Django में एक सुपर क्लास मॉडल क्षेत्र के वर्बोज़ नाम ओवरराइड करने के लिए

+0

उत्तर के लिए धन्यवाद! इसलिए हम या तो (i) किसी फ़ॉर्म के अंदर एक लेबल सेट कर सकते हैं, या (ii) _meta.get_fields विधि के माध्यम से कक्षा को परिभाषित करने के बाद verbose_name सेट कर सकते हैं। दोनों को कार्यान्वित करना आसान है, हालांकि मुझे लगता है कि मैं _meta.get_fields विधि का उपयोग करना पसंद करूंगा ताकि मैं मॉडल मॉड्यूल के अंदर सभी मॉडल-प्रासंगिक चीजें रख सकूं। – shanyu

उत्तर

49

एक सरल हैक मैं का इस्तेमाल किया है है:

class SuperFoo(models.Model): 
    name = models.CharField('name of SuperFoo instance', max_length=50) 
    ... 

class Foo(SuperFoo): 
    ... # do something that changes verbose_name of name field of SuperFoo 
Foo._meta.get_field('name').verbose_name = 'Whatever' 
+3

यह वास्तव में सुपरफू कक्षा के लिए फ़ील्ड के verbose_name को बदलता है। उदाहरण के लिए, यदि आपके पास है: क्लास बार (सुपरफू), 'name' फ़ील्ड के लिए verbose_name भी 'जो भी' है ... भले ही आप Bar._meta.get_field ('name') के साथ एक ही प्रक्रिया का पालन करें।verbose_name = 'जो भी 2' – mtaube

+2

यदि सुपरफू एक सार आधार वर्ग है, तो उपर्युक्त टिप्पणी सत्य नहीं है। यह विधि तब तक अच्छी तरह से काम करती है जब तक सुपरफू क्लास सारणी है, इसलिए कक्षा मेटा: सार = सही – mtaube

+0

क्या यह अभी भी सच है? – Pureferret

5

आपकी सर्वश्रेष्ठ शर्त फॉर्म में लेबल को सेट/बदलना होगा। nameFoo मॉडल (उदाहरण के लिए Foo._meta.fields में इसे देखकर) आपको SuperFoo के क्षेत्र का संदर्भ देगा, इसलिए verbose_name बदलकर इसे दोनों मॉडलों में बदल दिया जाएगा।

इसके अलावा, Foo वर्ग के लिए एक name क्षेत्र को जोड़ने के लिए, या तो काम नहीं करेगा because ...

एक माता पिता के मॉडल में ओवरराइड क्षेत्रों क्षेत्रों में कठिनाइयों की ओर जाता है इस तरह के रूप नई उदाहरणों initialising (निर्दिष्ट करने Model.__init__) और क्रमबद्धरण में कौन सा क्षेत्र अंतर्निहित किया जा रहा है। ये जो सामान्य अजगर वर्ग विरासत काफी उसी तरह से साथ निपटने के लिए नहीं है विशेषताएं हैं, तो Django मॉडल विरासत और अजगर वर्ग विरासत के बीच अंतर केवल मनमाना नहीं है।

5

कैसे Django-सीएमएस करता है, वे CMSPlugin से इनहेरिट मॉडल में db_table क्षेत्र ओवरराइड पर एक नज़र डालें। मूल बातें (जो मैं भी अपने खुद के सामान के लिए उपयोग करें) करने के लिए नीचे उबाल: आप कुछ चेकों जोड़ सकते हैं

class SuperFooMetaClass(ModelBase): 
    def __new__(cls, name, bases, attrs): 
     new_class = super(SuperFooMetaClass, cls).__new__(cls, name, bases, attrs) 
     new_class._meta.verbose_name = "...." # perhaps only if not customized 
     return new_class 


class SuperFoo(models.Model): 
    __metaclass__ = SuperFooMetaClass 

    .... 

, उदा केवल उप-वर्गों के लिए अद्यतन करें (प्रत्यक्ष प्रकार नहीं), या केवल तभी अद्यतन करें जब मान अनुकूलित नहीं किया गया हो।

10

Foo._meta.fields को संशोधित करने वाली चेतावनी को ध्यान में रखते हुए सुपरक्लास को भी प्रभावित किया जाएगा - और इसलिए सुपरक्लस अमूर्त होने पर ही वास्तव में उपयोगी होता है, मैंने उत्तर @ gerry को पुन: प्रयोज्य वर्ग सजावट के रूप में छोड़ दिया है:

def modify_fields(**kwargs): 
    def wrap(cls): 
     for field, prop_dict in kwargs.items(): 
      for prop, val in prop_dict.items(): 
       setattr(cls._meta.get_field(field), prop, val) 
     return cls 
    return wrap 

इस तरह यह प्रयोग करें:

@modify_fields(timestamp={ 
    'verbose_name': 'Available From', 
    'help_text': 'Earliest date you can book this'}) 
class Purchase(BaseOrderItem): 
    pass 

उपरोक्त उदाहरण विरासत में मिला क्षेत्र 'टाइमस्टैम्प' के लिए verbose_name और help_text बदल जाता है। आप कई कीवर्ड तर्कों में गुजर सकते हैं क्योंकि ऐसे फ़ील्ड हैं जिन्हें आप संशोधित करना चाहते हैं।

+0

धन्यवाद! यह Django 1.8 – pymarco

+0

का उपयोग कर मेरे लिए काम किया धन्यवाद! Django 1.11.4 पर एक आकर्षण की तरह काम किया। – emi

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