2010-08-12 11 views
22

मेरे पास एक कस्टम टैगफिल्ड फॉर्म फ़ील्ड है।Django व्यवस्थापक - एक कस्टम फॉर्म फ़ील्ड के विजेट को ओवरराइड करना

class TagField(forms.CharField): 
    def __init__(self, *args, **kwargs): 
     super(TagField, self).__init__(*args, **kwargs) 
     self.widget = forms.TextInput(attrs={'class':'tag_field'}) 

जैसा ऊपर देखा गया है, यह टेक्स्ट इनपुट फ़ॉर्म फ़ील्ड विजेट का उपयोग करता है। लेकिन व्यवस्थापक में मैं इसे Textarea विजेट का उपयोग करके प्रदर्शित करना चाहता हूं। इसके लिए, formfield_overrides हुक है लेकिन यह इस मामले के लिए काम नहीं करता है।

व्यवस्थापक घोषणा है:

class ProductAdmin(admin.ModelAdmin): 
    ... 
    formfield_overrides = { 
     TagField: {'widget': admin.widgets.AdminTextareaWidget}, 
    } 

यह फार्म क्षेत्र विजेट पर कोई प्रभाव नहीं है और अभी भी एक tags TextInput विजेट के साथ गाया जाता है।

किसी भी मदद की बहुत सराहना की जाती है। इस तरह अपने क्षेत्र बदलने के लिए
OMAT

उत्तर

40

django व्यवस्थापक अपने कई क्षेत्रों के लिए कस्टम विजेट का उपयोग करता है। फ़ील्ड को ओवरराइड करने का तरीका ModelAdmin ऑब्जेक्ट के साथ उपयोग के लिए एक फॉर्म बनाना है।

from django.contrib import admin 
from models import Product 
from forms import ProductAdminForm 

class ProductAdmin(admin.ModelAdmin): 
    form = ProductAdminForm 

admin.site.register(Product, ProductAdmin) 

तुम भी इस समय क्वेरीसमूह ओवरराइड कर सकते हैं:

# forms.py 

from django import forms 
from django.contrib import admin 

class ProductAdminForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(ProductAdminForm, self).__init__(*args, **kwargs) 
     self.fields['tags'].widget = admin.widgets.AdminTextareaWidget() 

फिर, अपने ModelAdmin वस्तु में, आप प्रपत्र निर्दिष्ट मॉडल में एक और क्षेत्र के अनुसार वस्तुओं फिल्टर करने के लिए, उदाहरण के लिए (के बाद से limit_choices_to इस संभाल सकते हैं)

+0

यह मेरे लिए काम नहीं करता है, आपको कक्षा के बजाय विजेट का एक उदाहरण पास करने की आवश्यकता है। उदाहरण पूरी तरह से काम किया, हालांकि। –

+0

मैं आमतौर पर admin.py में कस्टम व्यवस्थापक फॉर्म बनाउंगा और उन्हें form.py के साथ मिश्रित नहीं करूंगा। इससे अन्य डेवलपर्स के लिए कोई भी मिश्रण कम हो जाता है और सभी एडमिन विशिष्ट आइटम एक ही .py फ़ाइल में रखता है। – MaestroFJP

+0

अच्छा बिंदु @MestroFJP। मैं बस अपने नए कोड में कर रहा हूं। या, यदि आपके पास वास्तव में जटिल रूप हैं, और उनमें से बहुत सारे हैं, तो फॉर्म/admin.py का एक सबमिशन है। –

1

प्रयास करें -

:

class TagField(forms.CharField): 
    def __init__(self, *args, **kwargs): 
     self.widget = forms.TextInput(attrs={'class':'tag_field'}) 
     super(TagField, self).__init__(*args, **kwargs) 

इस विजेट जो **kwargs से आता है का उपयोग करने की अनुमति होगी। अन्यथा आपका क्षेत्र हमेशा form.TextInput विजेट का उपयोग करेगा।

+0

मैंने परिवर्तन लागू किया लेकिन अब सभी टैग फ़ील्ड Textarea के रूप में प्रस्तुत किए जाते हैं। – omat

+0

django.forms.fields को देखते हुए मैंने पाया कि एक क्षेत्र के लिए डिफ़ॉल्ट विजेट निर्दिष्ट करने के लिए सही तरीका है: वर्ग TagField (form.CharField): विजेट = forms.TextInput डीईएफ़ widget_attrs (स्वयं, विजेट): वापसी {'वर्ग': 'टैग_फील्ड'} आपने '__init__' विधि को ओवरराइड नहीं किया है। इसे इस्तेमाल करे। –

+0

धन्यवाद लेकिन अभी भी कोई भाग्य नहीं है। सभी टैग फ़ील्ड टेक्स्टएडा के रूप में प्रदर्शित होते हैं, सभी व्यवस्थापक पर, केवल उत्पाद एडमिन के लिए नहीं। – omat

27

आप Django 1.2 के बाद से विस्तार ModelForm मेटा वर्ग द्वारा क्षेत्र विगेट्स ओवरराइड कर सकते हैं:

class ProductAdminForm(forms.ModelForm): 
    class Meta: 
     model = Product 
     widgets = { 
      'tags': admin.widgets.AdminTextareaWidget 
     } 

class ProductAdmin(admin.ModelAdmin): 
    form = ProductAdminForm 

https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#overriding-the-default-fields

+3

Django 1.8 से शुरू करना आपको 'फ़ील्ड = '__all __'' मेटा' में जोड़ना चाहिए। Http://stackoverflow.com/a/28306347/1161025 के माध्यम से। – maciek

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