2009-03-26 13 views
12

पर आधारित व्यवस्थापक फ़ॉर्म को अनुकूलित करने के लिए get_form ओवरराइड करना मैंने इसे प्राप्त करने के लिए विभिन्न विधियों का प्रयास किया है।Django - अनुरोध

मैंने formfield_for_dbfield को ओवरराइड करने के खिलाफ निर्णय लिया क्योंकि इसे अनुरोध ऑब्जेक्ट की प्रति प्राप्त नहीं है और मैं थ्रेड_लोकल्स हैक से बचने की उम्मीद कर रहा था।

मैं अपने ModelAdmin कक्षा में get_form अधिभावी पर बसे और निम्नलिखित की कोशिश की:

class PageOptions(admin.ModelAdmin): 
    def get_form(self, request, obj=None, **kwargs): 
     if request.user.is_superuser: 
      self.fieldsets = ((None, {'fields': ('title','name',),}),) 
     else: 
      self.fieldsets = ((None, {'fields': ('title',),}),) 
     return super(PageOptions,self).get_form(request, obj=None, **kwargs) 

जब मैं get_form के भीतर से fieldsets या declared_fieldsets प्रिंट मैं कोई नहीं मिलता है (या जो भी मैं PageOptions में एक प्रारंभिक मूल्य के रूप में स्थापित)।

यह काम क्यों नहीं करता है और ऐसा करने का एक बेहतर तरीका है?

+1

क्या आपने पेजऑप्शन क्लास में कहीं भी फ़ील्डसेट घोषित करने का प्रयास किया है, यह देखने के लिए कि क्या यह काम करता है? –

+0

हाँ, यह शो कोई फर्क नहीं पड़ता कि get_form –

उत्तर

8

मुझे पता नहीं क्यों संपत्ति मुद्रण देना नहीं है आप तुम सिर्फ सौंपा चाहते हैं (मुझे लगता है कि हो सकता है कि आप जहां प्रिंट पर निर्भर करता है, वास्तव में), लेकिन अधिरोहण करने का प्रयास किया है:

यहाँ उदाहरण है इसके बजाय get_fieldsets। आधार कार्यान्वयन इस तरह दिखता है:

def get_fieldsets(self, request, obj=None): 
    if self.declared_fieldsets: 
     return self.declared_fieldsets 
    form = self.get_formset(request).form 
    return [(None, {'fields': form.base_fields.keys()})] 

अर्थात आप बस अपने tuples वापस करने में सक्षम होना चाहिए।

एंडीक द्वारा संपादित करें। 4 साल और मुझे किसी अन्य परियोजना पर कुछ करने की कोशिश करते समय फिर से अपना प्रश्न मिला।

def get_fieldsets(self, request, obj=None): 
    # Add 'item_type' on add forms and remove it on changeforms. 
    fieldsets = super(ItemAdmin, self).get_fieldsets(request, obj) 
    if not obj: # this is an add form 
     if 'item_type' not in fieldsets[0][1]['fields']: 
      fieldsets[0][1]['fields'] += ('item_type',) 
    else: # this is a change form 
     fieldsets[0][1]['fields'] = tuple(x for x in fieldsets[0][1]['fields'] if x!='item_type') 
    return fieldsets 
21

मेरे पास हाल ही की एक परियोजना से कुछ नमूना कोड है जो मुझे विश्वास है कि आपकी मदद कर सकता है। इस उदाहरण में, सुपर उपयोगकर्ता प्रत्येक फ़ील्ड को संपादित कर सकते हैं, जबकि हर किसी के पास "विवरण" फ़ील्ड को बाहर रखा गया है।

ध्यान दें कि मुझे लगता है कि यह उम्मीद है कि आप कक्षा get_form से वापस कर दें, जिससे आप सही काम नहीं कर रहे थे।

class EventForm(forms.ModelForm): 
    class Meta: 
     model = models.Event 
     exclude = ['description',] 

class EventAdminForm(forms.ModelForm): 
    class Meta: 
     model = models.Event 

class EventAdmin(admin.ModelAdmin): 

    def get_form(self, request, obj=None, **kwargs): 
     if request.user.is_superuser: 
      return EventAdminForm 
     else: 
      return EventForm 

admin.site.register(models.Event, EventAdmin) 
+0

में क्या है, यह वास्तव में सहायक लगता है। मैं अभी एक समय सीमा के बीच में हूं लेकिन मैं अगले हफ्ते इसे आजमाउंगा। पीएस मेरे सुपर कॉल परिणाम को एक फॉर्म में वापस नहीं किया जा रहा है? मैं सिर्फ पैरामीटर को संशोधित कर रहा हूं और वापस लौट रहा हूं कि get_form क्या लौटा होगा। –

+0

और इस समाधान के साथ फ़ील्ड का उपयोग करने के बारे में क्या? अगर हम get_forms का उपयोग करते हैं तो हम फ़ील्ड्स और डेटटाइमफ़िल्ड जावास्क्रिप्ट विजेट के लिए कॉन्फ़िगरेशन को खो देते हैं। धन्यवाद। – vmassuchetto

+1

https://docs.djangoproject.com/en/1.4/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_form बहुत बेहतर समाधान प्रतीत होता है। @ रयान-डफिल्ड – Saurabh

6

यह मेरा समाधान है: इस बार हालांकि थोड़ा संशोधित मैं इस दृष्टिकोण के साथ चला गया fieldsets परिभाषा को दोहराने के लिए होने से बचाने के

class MyModelAdmin(admin.ModelAdmin): 

    def get_form(self, request, obj=None, **kwargs): 
     if request.user.is_superuser: 
      self.exclude =() 
     else: 
      self.exclude = ('field_to_exclude',) 
     return super(MyModelAdmin, self).get_form(request, obj=None, **kwargs) 

आशा मदद कर सकते हैं

+1

फ़ील्ड को हटाने के बजाय, आप इसे केवल पढ़ने के लिए (डीजेगो 1.2 और ऊपर) बनाना चाहते हैं - केवल self.exclude के बजाय self.readonly_fields का उपयोग करें। – jturnbull

+0

यह थ्रेड-सुरक्षित नहीं है। या यह थ्रेड-सुरक्षित है क्योंकि आपके पास और शर्त है। Self.exclude के बजाय modifing kwargs ["बहिष्कृत करें"] का प्रयास करें। – pista329

3

मूल्य में बदलाव न करें स्वयं गुणों के कारण यह धागा-सुरक्षित नहीं है। आपको उन मानों को ओवरराइड करने के लिए जो भी हुक का उपयोग करना होगा।

6

अनुकूलित व्यवस्थापक रूपों के निर्माण के लिए हमने एक नई कक्षा को परिभाषित किया है जिसे मिश्रित के रूप में उपयोग किया जा सकता है।

  • ModelAdmin: एक fieldset सभी क्षेत्रों

    युक्त
  • ModelForm को परिभाषित: दृष्टिकोण काफी लचीला है संकीर्ण क्षेत्रों दिखाया जा रहा

  • FlexibleModelAdmin: अधिभावी ModelAdmin की get_fieldsets-विधि; एक कम fieldset कि केवल व्यवस्थापक प्रपत्र


class FlexibleModelAdmin(object): 
    ''' 
    adds the possibility to use a fieldset as template for the generated form 
    this class should be used as mix-in 
    ''' 

    def _filterFieldset(self, proposed, form): 
     ''' 
     remove fields from a fieldset that do not 
     occur in form itself. 
     ''' 

     allnewfields = [] 
     fields = form.base_fields.keys() 
     fieldset = [] 
     for fsname, fdict in proposed: 
      newfields = [] 
      for field in fdict.get('fields'): 
       if field in fields: 
        newfields.append(field) 
       allnewfields.extend(newfields) 
      if newfields: 
       newentry = {'fields': newfields} 
       fieldset.append([fsname, newentry]) 

     # nice solution but sets are not ordered ;) 
     # don't forget fields that are in a form but were forgotten 
     # in fieldset template 
     lostfields = list(set(fields).difference(allnewfields)) 
     if len(lostfields): 
      fieldset.append(['lost in space', {'fields': lostfields}]) 

     return fieldset 

    def get_fieldsets(self, request, obj=None): 
     ''' 
     Hook for specifying fieldsets for the add form. 
     ''' 

     if hasattr(self, 'fieldsets_proposed'): 
      form = self.get_form(request, obj) 
      return self._filterFieldset(self.fieldsets_proposed, form) 
     else: 
      return super(FlexibleModelAdmin, self).get_fieldsets(request, obj) 

व्यवस्थापक मॉडल आप fieldsets_proposed परिभाषित जो टेम्पलेट के रूप में कार्य करता है और सभी क्षेत्रों में शामिल है में में परिभाषित फ़ील्ड हैं देता है।

class ReservationAdmin(FlexibleModelAdmin, admin.ModelAdmin): 

    list_display = ['id', 'displayFullName'] 
    list_display_links = ['id', 'displayFullName'] 
    date_hierarchy = 'reservation_start' 
    ordering = ['-reservation_start', 'vehicle'] 
    exclude = ['last_modified_by'] 

    # considered by FlexibleModelAdmin as template 
    fieldsets_proposed = (
     (_('General'), { 
      'fields': ('vehicle', 'reservation_start', 'reservation_end', 'purpose') # 'added_by' 
     }), 
     (_('Report'), { 
      'fields': ('mileage') 
     }), 
     (_('Status'), { 
      'fields': ('active', 'editable') 
     }), 
     (_('Notes'), { 
      'fields': ('note') 
     }), 
    ) 
    ....   

    def get_form(self, request, obj=None, **kwargs): 
     ''' 
     set the form depending on the role of the user for the particular group 
     ''' 

     if request.user.is_superuser: 
      self.form = ReservationAdminForm 
     else: 
      self.form = ReservationUserForm 

     return super(ReservationAdmin, self).get_form(request, obj, **kwargs) 

admin.site.register(Reservation, ReservationAdmin) 

अपने मॉडल रूपों में अब आप फ़ील्ड को बाहर/शामिल करने के लिए परिभाषित कर सकते हैं। mixin-class के get_fieldset() यह सुनिश्चित करता है कि केवल फ़ॉर्म में परिभाषित फ़ील्ड लौटाए जा रहे हैं।

class ReservationAdminForm(ModelForm): 
    class Meta: 
     model = Reservation 
     exclude = ('added_by', 'last_modified_by') 

class ReservationUserForm(BaseReservationForm): 
    class Meta: 
     model = Reservation 
     fields = ('vehicle', 'reservation_start', 'reservation_end', 'purpose', 'note') 
0

आप बना सकते हैं fieldsets और form गुण और उन्हें संकेत फेंकना वांछित रूपों/fieldsets निकलना है।

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