2009-12-10 9 views
5

मैं आज तीन महीने के लिए Django का उपयोग कर रहा हूं और यह वास्तव में बहुत अच्छा है। फास्ट वेब अनुप्रयोग विकास।Django रूप में, कस्टम SelectField और SelectMultipleField

मेरे पास अभी भी एक चीज है जो मैं बिल्कुल नहीं कर सकता हूं कि मैं कैसे करना चाहता हूं। यह SelectField और SelectMultiple फ़ील्ड है।

मैं किसी चयन के विकल्प पर कुछ तर्क डाल सकता हूं।

मैं अंत में optgroup के साथ सफलता:

class EquipmentField(forms.ModelChoiceField): 
    def __init__(self, queryset, **kwargs): 
     super(forms.ModelChoiceField, self).__init__(**kwargs) 
     self.queryset = queryset 
     self.to_field_name=None 

     group = None 
     list = [] 
     self.choices = [] 

     for equipment in queryset: 
      if not group: 
       group = equipment.type 

      if group != equipment.type: 
       self.choices.append((group.name, list)) 
       group = equipment.type 
       list = [] 
      else: 
       list.append((equipment.id, equipment.name)) 

लेकिन एक ModelForm के लिए, मैं मॉडल के रंग संपत्ति का उपयोग कर, हर विकल्प की पृष्ठभूमि का रंग बदलना होगा।

क्या आप जानते हैं कि मैं यह कैसे कर सकता हूं?

धन्यवाद।

उत्तर

5

आपको क्या करना है, विजेट द्वारा नियंत्रित आउटपुट को बदलना है। डिफ़ॉल्ट चयन विजेट है, इसलिए आप इसे उपclass कर सकते हैं। ऐसा लगता है:

class Select(Widget): 
    def __init__(self, attrs=None, choices=()): 
     super(Select, self).__init__(attrs) 
     # choices can be any iterable, but we may need to render this widget 
     # multiple times. Thus, collapse it into a list so it can be consumed 
     # more than once. 
     self.choices = list(choices) 

    def render(self, name, value, attrs=None, choices=()): 
     if value is None: value = '' 
     final_attrs = self.build_attrs(attrs, name=name) 
     output = [u'<select%s>' % flatatt(final_attrs)] 
     options = self.render_options(choices, [value]) 
     if options: 
      output.append(options) 
     output.append('</select>') 
     return mark_safe(u'\n'.join(output)) 

    def render_options(self, choices, selected_choices): 
     def render_option(option_value, option_label): 
      option_value = force_unicode(option_value) 
      selected_html = (option_value in selected_choices) and u' selected="selected"' or '' 
      return u'<option value="%s"%s>%s</option>' % (
       escape(option_value), selected_html, 
       conditional_escape(force_unicode(option_label))) 
     # Normalize to strings. 
     selected_choices = set([force_unicode(v) for v in selected_choices]) 
     output = [] 
     for option_value, option_label in chain(self.choices, choices): 
      if isinstance(option_label, (list, tuple)): 
       output.append(u'<optgroup label="%s">' % escape(force_unicode(option_value))) 
       for option in option_label: 
        output.append(render_option(*option)) 
       output.append(u'</optgroup>') 
      else: 
       output.append(render_option(option_value, option_label)) 
     return u'\n'.join(output) 

यह बहुत सी कोड है। लेकिन आपको क्या करना है, एक संशोधित रेंडर विधि के साथ अपना खुद का विजेट बनाना है। यह रेंडर विधि है जो बनाई गई HTML को निर्धारित करती है। इस मामले में, यह render_options विधि है जिसे आपको बदलने की आवश्यकता है। यहां आप यह निर्धारित करने के लिए कुछ चेक शामिल कर सकते हैं कि कक्षा को कब जोड़ना है, जिसे आप शैली बना सकते हैं।

एक और बात, उपरोक्त आपके कोड में यह नहीं लगता कि आप अंतिम समूह विकल्पों को जोड़ते हैं। इसके अलावा आप क्वेरीसेट में order_by() जोड़ना चाहेंगे, क्योंकि आपको इसे टाइप करके ऑर्डर करने की आवश्यकता है। आप इसे init विधि में कर सकते हैं, इसलिए जब आप फॉर्म फ़ील्ड का उपयोग करते हैं तो आपको इसे पूरा करने की ज़रूरत नहीं है।

+0

ठीक है, तो मुझे एक पूर्ण SelectWidget बनाना चाहिए। मैं कोशिश करूँगा, धन्यवाद। – Natim

0

आपको प्रस्तुत किए गए HTML टैग में कुछ कस्टम विशेषताओं को जोड़ने के लिए फ़ॉर्म फ़ील्ड के साथ गड़बड़ नहीं करना चाहिए। लेकिन आपको उपclass और विजेट में इन्हें जोड़ना चाहिए।

docs: customizing-widget-instances

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

class CommentForm(forms.Form): 
    name = forms.CharField(
       widget=forms.TextInput(attrs={'class':'special'})) 
    url = forms.URLField() 
    comment = forms.CharField(
       widget=forms.TextInput(attrs={'size':'40'})) 
Django will then include the extra attributes in the rendered output: 

>>> f = CommentForm(auto_id=False) 
>>> f.as_table() 
<tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr> 
<tr><th>Url:</th><td><input type="text" name="url"/></td></tr> 
<tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr> 
+0

यह सामान्य क्षेत्र के लिए है। और मैं पहले से ही ऐसा करता हूं, लेकिन आप SelectWidget के विकल्प के लिए ऐसा कैसे करते हैं? – Natim

0

http://code.djangoproject.com/browser/django/trunk/django/newforms/widgets.py?rev=7083

रूप वर्ग का चयन करें (विजेट) के तहत देखी गई:, वहाँ कोई रास्ता नहीं एक विकल्प टैग करने के लिए शैली विशेषता जोड़ने के लिए है। इसके लिए, आपको इस विजेट को उपclass करना होगा और ऐसी कार्यक्षमता जोड़नी होगी।

वर्ग का चयन करें (विजेट): परिभाषा केवल कहते हैं मुख्य को शैली विशेषता टैग का चयन करें।

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