2010-05-02 29 views
7

में रीडरिंग फ़ील्ड मैं अपने django एप्लिकेशन में प्रत्येक मॉडल में कुछ फ़ील्ड जोड़ना चाहता हूं। इस बार यह created_at, updated_at और notes है। 20+ मॉडल में से प्रत्येक के लिए डुप्लिकेटिंग कोड गूंगा लगता है। इसलिए, मैंने अमूर्त बेस क्लास का उपयोग करने का निर्णय लिया जो इन क्षेत्रों को जोड़ देगा। समस्या यह है कि अमूर्त बेस क्लास से विरासत में प्राप्त क्षेत्र पहले व्यवस्थापक सूची में फ़ील्ड सूची में आते हैं। प्रत्येक मॉडल एडमिन क्लास के लिए फ़ील्ड ऑर्डर घोषित करना एक विकल्प नहीं है, मैन्युअल फील्ड घोषणा के मुकाबले यह और भी डुप्लिकेट कोड है।Django मॉडल

मेरा अंतिम समाधान में, मैं नया उदाहरण बनाने से पहले _meta में क्षेत्रों को पुन: व्यवस्थित करने के लिए मॉडल निर्माता संशोधित:

class MyModel(models.Model): 
    # Service fields 
    notes = my_fields.NotesField() 
    created_at = models.DateTimeField(auto_now_add=True) 
    updated_at = models.DateTimeField(auto_now=True) 

    class Meta: 
     abstract = True 

    last_fields = ("notes", "created_at", "updated_at") 
    def __init__(self, *args, **kwargs): 
     new_order = [f.name for f in self._meta.fields] 
     for field in self.last_fields: 
      new_order.remove(field) 
      new_order.append(field) 
     self._meta._field_name_cache.sort(key=lambda x: new_order.index(x.name)) 
     super(MyModel, self).__init__(*args, **kwargs) 

class ModelA(MyModel): 
    field1 = models.CharField() 
    field2 = models.CharField() 
    #etc ... 

यह अपेक्षित तरीके से काम, लेकिन मैं सोच रहा हूँ, वहाँ मेरा लक्ष्य हासिल करने के लिए एक बेहतर तरीका है ?

उत्तर

5

यदि आपको मुख्य रूप से Django के व्यवस्थापक के लिए आदेश की आवश्यकता है तो आप डीजेगो के प्रशासन वर्ग के उप-वर्गीकरण के माध्यम से अपनी "जेनेरिक" -डमिन कक्षा भी बना सकते हैं। व्यवस्थापक में फ़ील्ड के प्रदर्शन को अनुकूलित करने के लिए http://docs.djangoproject.com/en/dev/intro/tutorial02/#customize-the-admin-form देखें। व्यवस्थापक की उदाहरण के निर्माण पर फ़ील्ड/फ़ील्ड सेट अप करने के लिए आप व्यवस्थापक के __init__ को ओवरराइट कर सकते हैं। जैसे

class MyAdmin(admin.ModelAdmin): 
    def __init__(self, model, admin_site): 
     general_fields = ['notes', 'created_at', 'updated_at'] 
     fields = [f.name for f in self.model._meta.fields if f.name not in general_fields] 
     self.fields = fields + general_fields 
     super(admin.ModelAdmin, self).__init__(model, admin_site) 

कि इसके अलावा मुझे लगता है कि यह (निजी) _field_name_cache संशोधित करने के लिए एक अच्छा अभ्यास नहीं है: आप की तरह कुछ कर सकता है!

7

मैं बहुत ही समस्या हो रही थी, लेकिन मैंने पाया इन समाधानों समस्याग्रस्त किया जा करने के लिए है, तो यहाँ मैं क्या किया है:

class BaseAdmin(admin.ModelAdmin): 
    def get_fieldsets(self, request, obj = None): 
     res = super(BaseAdmin, self).get_fieldsets(request, obj) 
     # I only need to move one field; change the following 
     # line to account for more. 
     res[0][1]['fields'].append(res[0][1]['fields'].pop(0)) 
     return res 

व्यवस्थापक में fieldset बदलने, मेरे लिए और अधिक समझ में आता है खेतों को बदलने से मॉडल में

0

मुझे अन्य समाधान पसंद नहीं आया, इसलिए मैंने बस माइग्रेशन फ़ाइलों को सीधे संशोधित किया।

जब भी आप models.py में एक नई तालिका बनाते हैं, तो आपको "python manage.py makemigrations" चलाने की आवश्यकता होगी (मुझे यह Django> = v1.7.5 में विश्वास है)। एक बार ऐसा करने के बाद, your_app_path/migrations/ निर्देशिका में नव निर्मित माइग्रेशन फ़ाइल खोलें और पंक्तियों को उस क्रम में ले जाएं जिसे आप चाहते हैं। फिर "python manage.py माइग्रेट" चलाएं। देखा! "Python manage.py dbshell" में जाकर आप देख सकते हैं कि कॉलम का क्रम बिल्कुल ठीक है कि आप उन्हें कैसे चाहते थे!

इस विधि के लिए डाउनसाइड: आपको इसे बनाने वाली प्रत्येक तालिका के लिए मैन्युअल रूप से ऐसा करना है, लेकिन सौभाग्य से ओवरहेड न्यूनतम है। और यह केवल तभी किया जा सकता है जब आप एक नई तालिका बना रहे हों, मौजूदा को संशोधित न करें।