In Django form, custom SelectField and SelectMultipleField

后端 未结 5 1626
野趣味
野趣味 2021-01-02 16:11

I am using Django everyday now for three month and it is really great. Fast web application development.

I have still one thing that I cannot do exactly how I want t

5条回答
  •  庸人自扰
    2021-01-02 16:46

    render_option has been removed from Django 1.11 onwards. This is what I did to achieve this. A little bit of digging and this seems straightforward and neat. Works with Django 2.0+

    class CustomSelect(forms.Select):
        def __init__(self, attrs=None, choices=()):
            self.custom_attrs = {}
            super().__init__(attrs, choices)
    
        def create_option(self, name, value, label, selected, index, subindex=None, attrs=None):
            index = str(index) if subindex is None else "%s_%s" % (index, subindex)
            if attrs is None:
                attrs = {}
            option_attrs = self.build_attrs(self.attrs, attrs) if self.option_inherits_attrs else {}
            if selected:
                option_attrs.update(self.checked_attribute)
            if 'id' in option_attrs:
                option_attrs['id'] = self.id_for_label(option_attrs['id'], index)
    
            # setting the attributes here for the option
            if len(self.custom_attrs) > 0:
                if value in self.custom_attrs:
                    custom_attr = self.custom_attrs[value]
                    for k, v in custom_attr.items():
                        option_attrs.update({k: v})
    
            return {
                'name': name,
                'value': value,
                'label': label,
                'selected': selected,
                'index': index,
                'attrs': option_attrs,
                'type': self.input_type,
                'template_name': self.option_template_name,
            }
    
    
    class MyModelChoiceField(ModelChoiceField):
    
        # custom method to label the option field
        def label_from_instance(self, obj):
            # since the object is accessible here you can set the extra attributes
            if hasattr(obj, 'type'):
                self.widget.custom_attrs.update({obj.pk: {'type': obj.type}})
            return obj.get_display_name()
    

    The form:

    class BookingForm(forms.ModelForm):
    
        customer = MyModelChoiceField(required=True,
                                      queryset=Customer.objects.filter(is_active=True).order_by('name'),
                                      widget=CustomSelect(attrs={'class': 'chosen-select'}))
    

    The output which I needed is as:

      
                            
        
    提交评论

提交回复
热议问题