This might be a late answer but this is a simplified version that can be modified using the form instance.
You can either pass a list of values to be disabled i.e def __init__(self, disabled_choices, *args, **kwargs): self.disabled_choices = disabled_choices OR from django.forms import Select class SelectWidget(Select): """ Subclass of Django's select widget that allows disabling options. """ def __init__(self, *args, **kwargs): self._disabled_choices = [] super(SelectWidget, self).__init__(*args, **kwargs) @property def disabled_choices(self): return self._disabled_choices @disabled_choices.setter def disabled_choices(self, other): self._disabled_choices = other def create_option(self, name, value, label, selected, index, subindex= None, attrs=None): option_dict = super(SelectWidget, self).create_option( name, value, label, selected, index, subindex=subindex, attrs= attrs ) if value in self.disabled_choices: option_dict['attrs']['disabled'] = 'disabled' return option_dict To disabled an option based on a condition i.e user isn't a superuser. class MyForm(forms.Form): status = forms.ChoiceField(required=True, widget=SelectWidget, choices= Status.choices()) def __init__(self, request, *args, **kwargs): if not request.user.is_superuser: self.fields['status'].widget.disabled_choices = [1, 4] super().__init__(*args, **kwargs) On Friday, June 3, 2011 at 12:50:12 PM UTC-4, Jody McIntyre wrote: > > We need to be able to disable choices in a <select>, which is done by > setting the disabled attribute on the <option> tag, for example: > <option value="bananas" disabled="disabled">Bananas</option> > > Currently we're doing this by subclassing the Select widget: > http://djangosnippets.org/snippets/2453/ > > It would be nice if the built in Select widget supported this. One way > would be to replace the existing render_option method with what I've > written, and I can prepare a patch if desired, but this approach changes > the format of the "choices" data structure to something that won't be > understood by other widgets. Perhaps these widgets should be improved too, > but I don't want to do this unless my changes have a good chance of being > accepted. > > I logged this as a ticket (16149) and was told to discuss it here. To > address aagustin's comments: > > 1. Backwards compatibility is already addressed. If the widget is passed > a regular "choices" field, the existing behavior is preserved. > > 2. I don't understand what you mean by "boilerplate" in the API. A > "choices" field with a disabled choice looks like: > > choices = (('apples', 'Apples'), > ('oranges', 'Oranges'), > ('bananas', {'label': 'Bananas', > 'disabled': True}), > ('grobblefruit', 'Grobblefruit')) > > I can't think of a more concise way of clearly representing that 'bananas' > is disabled while still allowing it to have a label, unless we want to > change the "choices" data structure a lot more to something like: > > choices = (('apples', 'Apples'), > ('oranges', 'Oranges'), > ('bananas', 'Bananas', {'disabled': True}), > ('grobblefruit', 'Grobblefruit')) > > Suggestions & other thoughts welcome :) > Jody > -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at https://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/bfb05112-e288-48c9-8daa-dbb9ece149d7%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.