How to add attributes to option tags in django ?

iva123 picture iva123 · Jun 25, 2011 · Viewed 15k times · Source

I have to add title attribute to options of the ModelChoiceField. Here is my admin code for that:

class LocModelForm(forms.ModelForm):
        def __init__(self,*args,**kwargs):
            super(LocModelForm,self).__init__(*args,**kwargs)
            self.fields['icons'] = forms.ModelChoiceField(queryset = Photo.objects.filter(galleries__title_slug = "markers"))
            self.fields['icons'].widget.attrs['class'] = 'mydds'


        class Meta:
            model = Loc
            widgets = {
                'icons' : forms.Select(attrs={'id':'mydds'}), 
                }

        class Media:
            css = {
                "all":("/media/css/dd.css",)
                }
            js=(
                '/media/js/dd.js',
                )

class LocAdmin(admin.ModelAdmin):
    form = LocModelForm

I can add any attribute to select widget, but i don't know how to add attributes to option tags. Any idea ?

Answer

Cat Plus Plus picture Cat Plus Plus · Jun 25, 2011

First of all, don't modify fields in __init__, if you want to override widgets use Meta inner class, if you want to override form fields, declare them like in a normal (non-model) form.

If the Select widget does not do what you want, then simply make your own. Original widget uses render_option method to get HTML representation for a single option — make a subclass, override it, and add whatever you want.

class MySelect(forms.Select):
    def render_option(self, selected_choices, option_value, option_label):
        # look at the original for something to start with
        return u'<option whatever>...</option>'

class LocModelForm(forms.ModelForm):
    icons = forms.ModelChoiceField(
        queryset = Photo.objects.filter(galleries__title_slug = "markers"),
        widget = MySelect(attrs = {'id': 'mydds'})
    )

    class Meta:
        # ...
        # note that if you override the entire field, you don't have to override
        # the widget here
    class Media:
        # ...