“Disabled” option for choiceField - DjangoHow to customise attributes of forms.Select options in DjangoDisabled option in Django Select Widget using ModelChoiceFieldDoes Django scale?differentiate null=True, blank=True in djangodjango: How to use ModelForm with dynamic 0-n possibilities?django countries dropdown defaultdisplaying errors with django ModelFormDynamic Fields ModelForms DjangoDjango: adding an “Add new” button for a ForeignKey in a ModelFormDjango Rest Framework with ChoiceFieldType error object is not JSON serializable when using ChoiceField
To what extent would a wizard be able to combine feats to learn to mimic unknown spells?
Yet another hash table in C
Is this a reference to the film Alien in the novel 2010 Odyssey Two?
What is this little owl-like bird?
How do we handle pauses in a dialogue?
How to drill holes in 3/8" steel plates?
What in New Testament invalidates God’s commandments from the Old Testament?
Is it possible to see individual photons impressioning film?
When an electron changes its spin, or any other intrinsic property, is it still the same electron?
Efficiently defining a SparseArray function
Why do we need common sense in AI?
What happens to unproductive professors?
Why does the US seem to have a rather low economic interest in Africa?
Why is a mixture of two normally distributed variables only bimodal if their means differ by at least two times the common standard deviation?
Does a wizard need their hands free in order to cause their familiar from the Find Familiar spell to reappear?
How to compare the ls output of two folders to find a missing directory?
"was fiction" vs "were fictions"
When I press the space bar it deletes the letters in front of it
Can Jimmy hang on his rope?
Is it OK to leave real names & info visible in business card portfolio?
WTB Horizon 47c - small crack in the middle of the tire
The three greedy pirates
Why weren't bootable game disks ever a thing on the IBM PC?
What is the right approach to quit a job during probation period for a competing offer?
“Disabled” option for choiceField - Django
How to customise attributes of forms.Select options in DjangoDisabled option in Django Select Widget using ModelChoiceFieldDoes Django scale?differentiate null=True, blank=True in djangodjango: How to use ModelForm with dynamic 0-n possibilities?django countries dropdown defaultdisplaying errors with django ModelFormDynamic Fields ModelForms DjangoDjango: adding an “Add new” button for a ForeignKey in a ModelFormDjango Rest Framework with ChoiceFieldType error object is not JSON serializable when using ChoiceField
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I having trouble with a simple question :
How to have some "disabled" field in a dropdown menu generated via a modelForm and choiceFied in the django Framework ?
At the moment, I cannot figure out how to obtain such an output :
-- Root 1 entry -- (disabled)
-- Elt 1 -- (not disabled)
-- Root 2 entry -- (disabled)
Do you have any advice ?
Pierre
django
add a comment |
I having trouble with a simple question :
How to have some "disabled" field in a dropdown menu generated via a modelForm and choiceFied in the django Framework ?
At the moment, I cannot figure out how to obtain such an output :
-- Root 1 entry -- (disabled)
-- Elt 1 -- (not disabled)
-- Root 2 entry -- (disabled)
Do you have any advice ?
Pierre
django
This is still an open issue: code.djangoproject.com/ticket/16149
– tobib
May 28 at 15:30
add a comment |
I having trouble with a simple question :
How to have some "disabled" field in a dropdown menu generated via a modelForm and choiceFied in the django Framework ?
At the moment, I cannot figure out how to obtain such an output :
-- Root 1 entry -- (disabled)
-- Elt 1 -- (not disabled)
-- Root 2 entry -- (disabled)
Do you have any advice ?
Pierre
django
I having trouble with a simple question :
How to have some "disabled" field in a dropdown menu generated via a modelForm and choiceFied in the django Framework ?
At the moment, I cannot figure out how to obtain such an output :
-- Root 1 entry -- (disabled)
-- Elt 1 -- (not disabled)
-- Root 2 entry -- (disabled)
Do you have any advice ?
Pierre
django
django
asked Mar 23 '09 at 12:30
PierrePierre
1481 gold badge1 silver badge6 bronze badges
1481 gold badge1 silver badge6 bronze badges
This is still an open issue: code.djangoproject.com/ticket/16149
– tobib
May 28 at 15:30
add a comment |
This is still an open issue: code.djangoproject.com/ticket/16149
– tobib
May 28 at 15:30
This is still an open issue: code.djangoproject.com/ticket/16149
– tobib
May 28 at 15:30
This is still an open issue: code.djangoproject.com/ticket/16149
– tobib
May 28 at 15:30
add a comment |
7 Answers
7
active
oldest
votes
Django's form widgets offer a way to pass a list of attributes that should be rendered on the <option>
tag:
my_choices = ( ('one', 'One'), ('two', 'Two'))
class MyForm(forms.Form):
some_field = forms.ChoiceField(choices=my_choices,
widget=forms.Select(attrs='disabled':'disabled'))
Unfortunately, this won't work for you because the attribute will be applied to EVERY option tag that is rendered. Django has no way to automatically know which should be enabled and which should be disabled.
In your case, I recommend writing a custom widget. It's pretty easy to do, and you don't have that much custom logic to apply. The docs on this are here. In short though:
- subclass
forms.Select
, which is the default select renderer - in your subclass, implement the
render(self, name, value, attrs)
method. Use your custom logic to determine if thevalue
qualifies as needing to be disabled. Have a look at the very short implementation ofrender
indjango/forms/widgets.py
if you need inspriation.
Then, define your form field to use your custom widget:
class MyForm(forms.Form):
some_field = forms.ChoiceField(choices=my_choices,
widget=MyWidget)
1
This is a very nice solution, but the proper method to change the options' attributes isrender_option()
notrender()
(which renders the whole widget)
– jnns
Oct 4 '10 at 16:08
And remember to implement corresponding field validation too. Just disabling an option in HTML isn't enough if you don't want the option to be used.
– Jeewes
Dec 10 '18 at 7:49
This offers a good start, though I've greatly expanded on this answer in my solution below: stackoverflow.com/questions/673199/…
– Rob
Mar 26 at 1:15
add a comment |
You can create Choices as mentioned by Bryan like this. In the below options Root 1, Root 2 are automatically disabled and they will look like Group Options
CHOICES = (
('-- Root 1--',
(
('ELT1', 'ELT1'),
('ELT2', 'ELT2'),
('ELT3', 'ELT3'),
)
),
('-- Root 2--',
(
('ELT3', 'ELT3'),
('ELT4', 'ELT4'),
)
),
)
The above option will display like this. In the below image, Root 1 and Root 2 are not selectable.
Hope this will clear your problem
-Vikram
add a comment |
It seems django 1.1 will allow "optgroup": Django documentation
class MyForm(forms.Form):
some_field = forms.ChoiceField(choices=[
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
('unknown', 'Unknown'),
])
This imho is a must have.
add a comment |
Are you trying to create a menu in which the list items are separated into categories, and you don't want the categories themselves to be selectable?
If so, you can achieve this by having your template render the field using tags, e.g.
<select name="my_field" id="id_my_field">
<optgroup label="-- Root 1 entry --">
<option value="1">Elt 1</option>
<option value="2">Elt 2</option>
<option value="3">Elt 3</option>
</optgroup>
<optgroup label="--- Root 2 entry ---">
<option value="4">Elt 4</option>
<option value="5">Elt 5</option>
</optgroup>
</select>
add a comment |
field_choices = (
('','Make choice'),
(1,'first'),
(2,'second'),
(3,'third')
)
from django.forms import Select
class Select(Select):
def create_option(self, *args,**kwargs):
option = super().create_option(*args,**kwargs)
if not option.get('value'):
option['attrs']['disabled'] = 'disabled'
if option.get('value') == 2:
option['attrs']['disabled'] = 'disabled'
return option
add a comment |
Simple questions sometimes have complex answers in Django. I spent a lot of time getting this to work well. Combining Jarrett's overview with an important note from jnns about render_option
and some help from #django on freenode I have a well-working complete example solution:
First, this example assumes a normally defined choices-type CharField in a model I call Rule. I subclass my own TimeStampedModel
but you can use a models.Model
:
class Rule(TimeStampedModel):
...
# Rule Type
SHORT_TERM_RULE = 'ST'
MAX_SIGHTINGS_PER_PERIOD_RULE = "MA"
WHITE_LIST_RULE = "WL"
BLACK_LIST_RULE = "BL"
RULE_CHOICES = (
(SHORT_TERM_RULE, 'Short Term Rule'),
(MAX_SIGHTINGS_PER_PERIOD_RULE, 'Max Sightings Per Period Rule'),
(WHITE_LIST_RULE, 'White List Rule'),
(BLACK_LIST_RULE, 'Black List Rule'),
)
rule_type = models.CharField(
max_length=2,
choices=RULE_CHOICES,
default=SHORT_TERM_RULE,
)
...
In forms.py, define the widget subclassing Select
that accepts disabled_choices
. It has a custom render_option()
that adds disabled
to the html output of option tags if their choice is included on the passed in disabled_choices
list. Note, I left most of the render_option()
code from Select
as-is:
class MySelect(Select):
def __init__(self, attrs=None, choices=(), disabled_choices=()):
super(MySelect, self).__init__(attrs, choices=choices)
self.disabled_choices = disabled_choices
def render_option(self, selected_choices, option_value, option_label):
if option_value is None:
option_value = ''
option_value = force_text(option_value)
if option_value in selected_choices:
selected_html = mark_safe(' selected="selected"')
if not self.allow_multiple_selected:
selected_choices.remove(option_value)
else:
selected_html = ''
for key, value in self.disabled_choices:
if option_value in key:
return format_html('<option disabled value=""></option>', option_value, selected_html,
force_text(option_label))
return format_html('<option value=""></option>', option_value, selected_html, force_text(option_label))
Then, in defining the form subclassing ModelForm
, check for a passed-in disabled_choices
list and initialize the field accordingly. In this example, I also sneak in a default choice.
class RuleChoiceForm(ModelForm):
class Meta:
model = Rule
fields = ['rule_type']
# Add a default choice to the list defined in the Rule model
default_choice = ('DF', 'Choose a Rule Type...')
choices = list(Rule.RULE_CHOICES)
choices.insert(0, default_choice)
choices = tuple(choices)
rule_type = forms.ChoiceField(widget=MySelect(attrs='class': 'form-control', disabled_choices=[]),
choices=choices)
def __init__(self, *args, disabled_choices=None, **kwargs):
super(RuleChoiceForm, self).__init__(*args, **kwargs)
if disabled_choices:
self.fields['rule_type'].widget.disabled_choices = disabled_choices
Then in your view, define disabled_choices
as a list, appending choices from your _CHOICES
var in your model and pass it into the form instantiation. In my logic, I use list comprehension of RULE_CHOICES
to get the tuple of the choice I want to disable. Though there may be a simpler way, please feel free to post suggestions to simplify or improve this answer.
disabled_choices = []
# Logic disabling choices
if Rule.objects.filter(route=route, rule_type=Rule.SHORT_TERM_RULE).exists():
disabled_choices.append([item for item in Rule.RULE_CHOICES if Rule.SHORT_TERM_RULE in item][0])
disabled_choices.append([item for item in Rule.RULE_CHOICES if Rule.MAX_SIGHTINGS_PER_PERIOD_RULE in item][0])
rule_choice_form = RuleChoiceForm(disabled_choices=disabled_choices)
add a comment |
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=(('on', 'On'), ('off', 'Off')))
def __init__(self, request, *args, **kwargs):
if not request.user.is_superuser:
self.fields['status'].widget.disabled_choices = ['off']
super().__init__(*args, **kwargs)
Excuse me I don't understand what is "Status" in "choices=Status.choices()"
– lese
May 24 at 6:22
This is a helper function for managing choice values using IntEnum or Enum types docs.python.org/3/library/enum.html blog post blog.richard.do/2014/02/18/…
– jackotonye
Jun 20 at 16:20
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f673199%2fdisabled-option-for-choicefield-django%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
7 Answers
7
active
oldest
votes
7 Answers
7
active
oldest
votes
active
oldest
votes
active
oldest
votes
Django's form widgets offer a way to pass a list of attributes that should be rendered on the <option>
tag:
my_choices = ( ('one', 'One'), ('two', 'Two'))
class MyForm(forms.Form):
some_field = forms.ChoiceField(choices=my_choices,
widget=forms.Select(attrs='disabled':'disabled'))
Unfortunately, this won't work for you because the attribute will be applied to EVERY option tag that is rendered. Django has no way to automatically know which should be enabled and which should be disabled.
In your case, I recommend writing a custom widget. It's pretty easy to do, and you don't have that much custom logic to apply. The docs on this are here. In short though:
- subclass
forms.Select
, which is the default select renderer - in your subclass, implement the
render(self, name, value, attrs)
method. Use your custom logic to determine if thevalue
qualifies as needing to be disabled. Have a look at the very short implementation ofrender
indjango/forms/widgets.py
if you need inspriation.
Then, define your form field to use your custom widget:
class MyForm(forms.Form):
some_field = forms.ChoiceField(choices=my_choices,
widget=MyWidget)
1
This is a very nice solution, but the proper method to change the options' attributes isrender_option()
notrender()
(which renders the whole widget)
– jnns
Oct 4 '10 at 16:08
And remember to implement corresponding field validation too. Just disabling an option in HTML isn't enough if you don't want the option to be used.
– Jeewes
Dec 10 '18 at 7:49
This offers a good start, though I've greatly expanded on this answer in my solution below: stackoverflow.com/questions/673199/…
– Rob
Mar 26 at 1:15
add a comment |
Django's form widgets offer a way to pass a list of attributes that should be rendered on the <option>
tag:
my_choices = ( ('one', 'One'), ('two', 'Two'))
class MyForm(forms.Form):
some_field = forms.ChoiceField(choices=my_choices,
widget=forms.Select(attrs='disabled':'disabled'))
Unfortunately, this won't work for you because the attribute will be applied to EVERY option tag that is rendered. Django has no way to automatically know which should be enabled and which should be disabled.
In your case, I recommend writing a custom widget. It's pretty easy to do, and you don't have that much custom logic to apply. The docs on this are here. In short though:
- subclass
forms.Select
, which is the default select renderer - in your subclass, implement the
render(self, name, value, attrs)
method. Use your custom logic to determine if thevalue
qualifies as needing to be disabled. Have a look at the very short implementation ofrender
indjango/forms/widgets.py
if you need inspriation.
Then, define your form field to use your custom widget:
class MyForm(forms.Form):
some_field = forms.ChoiceField(choices=my_choices,
widget=MyWidget)
1
This is a very nice solution, but the proper method to change the options' attributes isrender_option()
notrender()
(which renders the whole widget)
– jnns
Oct 4 '10 at 16:08
And remember to implement corresponding field validation too. Just disabling an option in HTML isn't enough if you don't want the option to be used.
– Jeewes
Dec 10 '18 at 7:49
This offers a good start, though I've greatly expanded on this answer in my solution below: stackoverflow.com/questions/673199/…
– Rob
Mar 26 at 1:15
add a comment |
Django's form widgets offer a way to pass a list of attributes that should be rendered on the <option>
tag:
my_choices = ( ('one', 'One'), ('two', 'Two'))
class MyForm(forms.Form):
some_field = forms.ChoiceField(choices=my_choices,
widget=forms.Select(attrs='disabled':'disabled'))
Unfortunately, this won't work for you because the attribute will be applied to EVERY option tag that is rendered. Django has no way to automatically know which should be enabled and which should be disabled.
In your case, I recommend writing a custom widget. It's pretty easy to do, and you don't have that much custom logic to apply. The docs on this are here. In short though:
- subclass
forms.Select
, which is the default select renderer - in your subclass, implement the
render(self, name, value, attrs)
method. Use your custom logic to determine if thevalue
qualifies as needing to be disabled. Have a look at the very short implementation ofrender
indjango/forms/widgets.py
if you need inspriation.
Then, define your form field to use your custom widget:
class MyForm(forms.Form):
some_field = forms.ChoiceField(choices=my_choices,
widget=MyWidget)
Django's form widgets offer a way to pass a list of attributes that should be rendered on the <option>
tag:
my_choices = ( ('one', 'One'), ('two', 'Two'))
class MyForm(forms.Form):
some_field = forms.ChoiceField(choices=my_choices,
widget=forms.Select(attrs='disabled':'disabled'))
Unfortunately, this won't work for you because the attribute will be applied to EVERY option tag that is rendered. Django has no way to automatically know which should be enabled and which should be disabled.
In your case, I recommend writing a custom widget. It's pretty easy to do, and you don't have that much custom logic to apply. The docs on this are here. In short though:
- subclass
forms.Select
, which is the default select renderer - in your subclass, implement the
render(self, name, value, attrs)
method. Use your custom logic to determine if thevalue
qualifies as needing to be disabled. Have a look at the very short implementation ofrender
indjango/forms/widgets.py
if you need inspriation.
Then, define your form field to use your custom widget:
class MyForm(forms.Form):
some_field = forms.ChoiceField(choices=my_choices,
widget=MyWidget)
answered Mar 23 '09 at 21:16
Jarret HardieJarret Hardie
69.9k9 gold badges115 silver badges116 bronze badges
69.9k9 gold badges115 silver badges116 bronze badges
1
This is a very nice solution, but the proper method to change the options' attributes isrender_option()
notrender()
(which renders the whole widget)
– jnns
Oct 4 '10 at 16:08
And remember to implement corresponding field validation too. Just disabling an option in HTML isn't enough if you don't want the option to be used.
– Jeewes
Dec 10 '18 at 7:49
This offers a good start, though I've greatly expanded on this answer in my solution below: stackoverflow.com/questions/673199/…
– Rob
Mar 26 at 1:15
add a comment |
1
This is a very nice solution, but the proper method to change the options' attributes isrender_option()
notrender()
(which renders the whole widget)
– jnns
Oct 4 '10 at 16:08
And remember to implement corresponding field validation too. Just disabling an option in HTML isn't enough if you don't want the option to be used.
– Jeewes
Dec 10 '18 at 7:49
This offers a good start, though I've greatly expanded on this answer in my solution below: stackoverflow.com/questions/673199/…
– Rob
Mar 26 at 1:15
1
1
This is a very nice solution, but the proper method to change the options' attributes is
render_option()
not render()
(which renders the whole widget)– jnns
Oct 4 '10 at 16:08
This is a very nice solution, but the proper method to change the options' attributes is
render_option()
not render()
(which renders the whole widget)– jnns
Oct 4 '10 at 16:08
And remember to implement corresponding field validation too. Just disabling an option in HTML isn't enough if you don't want the option to be used.
– Jeewes
Dec 10 '18 at 7:49
And remember to implement corresponding field validation too. Just disabling an option in HTML isn't enough if you don't want the option to be used.
– Jeewes
Dec 10 '18 at 7:49
This offers a good start, though I've greatly expanded on this answer in my solution below: stackoverflow.com/questions/673199/…
– Rob
Mar 26 at 1:15
This offers a good start, though I've greatly expanded on this answer in my solution below: stackoverflow.com/questions/673199/…
– Rob
Mar 26 at 1:15
add a comment |
You can create Choices as mentioned by Bryan like this. In the below options Root 1, Root 2 are automatically disabled and they will look like Group Options
CHOICES = (
('-- Root 1--',
(
('ELT1', 'ELT1'),
('ELT2', 'ELT2'),
('ELT3', 'ELT3'),
)
),
('-- Root 2--',
(
('ELT3', 'ELT3'),
('ELT4', 'ELT4'),
)
),
)
The above option will display like this. In the below image, Root 1 and Root 2 are not selectable.
Hope this will clear your problem
-Vikram
add a comment |
You can create Choices as mentioned by Bryan like this. In the below options Root 1, Root 2 are automatically disabled and they will look like Group Options
CHOICES = (
('-- Root 1--',
(
('ELT1', 'ELT1'),
('ELT2', 'ELT2'),
('ELT3', 'ELT3'),
)
),
('-- Root 2--',
(
('ELT3', 'ELT3'),
('ELT4', 'ELT4'),
)
),
)
The above option will display like this. In the below image, Root 1 and Root 2 are not selectable.
Hope this will clear your problem
-Vikram
add a comment |
You can create Choices as mentioned by Bryan like this. In the below options Root 1, Root 2 are automatically disabled and they will look like Group Options
CHOICES = (
('-- Root 1--',
(
('ELT1', 'ELT1'),
('ELT2', 'ELT2'),
('ELT3', 'ELT3'),
)
),
('-- Root 2--',
(
('ELT3', 'ELT3'),
('ELT4', 'ELT4'),
)
),
)
The above option will display like this. In the below image, Root 1 and Root 2 are not selectable.
Hope this will clear your problem
-Vikram
You can create Choices as mentioned by Bryan like this. In the below options Root 1, Root 2 are automatically disabled and they will look like Group Options
CHOICES = (
('-- Root 1--',
(
('ELT1', 'ELT1'),
('ELT2', 'ELT2'),
('ELT3', 'ELT3'),
)
),
('-- Root 2--',
(
('ELT3', 'ELT3'),
('ELT4', 'ELT4'),
)
),
)
The above option will display like this. In the below image, Root 1 and Root 2 are not selectable.
Hope this will clear your problem
-Vikram
answered Dec 26 '12 at 15:54
vkramsvkrams
3,36714 gold badges53 silver badges91 bronze badges
3,36714 gold badges53 silver badges91 bronze badges
add a comment |
add a comment |
It seems django 1.1 will allow "optgroup": Django documentation
class MyForm(forms.Form):
some_field = forms.ChoiceField(choices=[
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
('unknown', 'Unknown'),
])
This imho is a must have.
add a comment |
It seems django 1.1 will allow "optgroup": Django documentation
class MyForm(forms.Form):
some_field = forms.ChoiceField(choices=[
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
('unknown', 'Unknown'),
])
This imho is a must have.
add a comment |
It seems django 1.1 will allow "optgroup": Django documentation
class MyForm(forms.Form):
some_field = forms.ChoiceField(choices=[
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
('unknown', 'Unknown'),
])
This imho is a must have.
It seems django 1.1 will allow "optgroup": Django documentation
class MyForm(forms.Form):
some_field = forms.ChoiceField(choices=[
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
('unknown', 'Unknown'),
])
This imho is a must have.
edited Dec 9 '16 at 12:53
Flimm
58.7k24 gold badges148 silver badges166 bronze badges
58.7k24 gold badges148 silver badges166 bronze badges
answered Mar 24 '09 at 8:29
PierrePierre
1481 gold badge1 silver badge6 bronze badges
1481 gold badge1 silver badge6 bronze badges
add a comment |
add a comment |
Are you trying to create a menu in which the list items are separated into categories, and you don't want the categories themselves to be selectable?
If so, you can achieve this by having your template render the field using tags, e.g.
<select name="my_field" id="id_my_field">
<optgroup label="-- Root 1 entry --">
<option value="1">Elt 1</option>
<option value="2">Elt 2</option>
<option value="3">Elt 3</option>
</optgroup>
<optgroup label="--- Root 2 entry ---">
<option value="4">Elt 4</option>
<option value="5">Elt 5</option>
</optgroup>
</select>
add a comment |
Are you trying to create a menu in which the list items are separated into categories, and you don't want the categories themselves to be selectable?
If so, you can achieve this by having your template render the field using tags, e.g.
<select name="my_field" id="id_my_field">
<optgroup label="-- Root 1 entry --">
<option value="1">Elt 1</option>
<option value="2">Elt 2</option>
<option value="3">Elt 3</option>
</optgroup>
<optgroup label="--- Root 2 entry ---">
<option value="4">Elt 4</option>
<option value="5">Elt 5</option>
</optgroup>
</select>
add a comment |
Are you trying to create a menu in which the list items are separated into categories, and you don't want the categories themselves to be selectable?
If so, you can achieve this by having your template render the field using tags, e.g.
<select name="my_field" id="id_my_field">
<optgroup label="-- Root 1 entry --">
<option value="1">Elt 1</option>
<option value="2">Elt 2</option>
<option value="3">Elt 3</option>
</optgroup>
<optgroup label="--- Root 2 entry ---">
<option value="4">Elt 4</option>
<option value="5">Elt 5</option>
</optgroup>
</select>
Are you trying to create a menu in which the list items are separated into categories, and you don't want the categories themselves to be selectable?
If so, you can achieve this by having your template render the field using tags, e.g.
<select name="my_field" id="id_my_field">
<optgroup label="-- Root 1 entry --">
<option value="1">Elt 1</option>
<option value="2">Elt 2</option>
<option value="3">Elt 3</option>
</optgroup>
<optgroup label="--- Root 2 entry ---">
<option value="4">Elt 4</option>
<option value="5">Elt 5</option>
</optgroup>
</select>
answered Mar 23 '09 at 21:02
bryanbryan
1,6741 gold badge19 silver badges19 bronze badges
1,6741 gold badge19 silver badges19 bronze badges
add a comment |
add a comment |
field_choices = (
('','Make choice'),
(1,'first'),
(2,'second'),
(3,'third')
)
from django.forms import Select
class Select(Select):
def create_option(self, *args,**kwargs):
option = super().create_option(*args,**kwargs)
if not option.get('value'):
option['attrs']['disabled'] = 'disabled'
if option.get('value') == 2:
option['attrs']['disabled'] = 'disabled'
return option
add a comment |
field_choices = (
('','Make choice'),
(1,'first'),
(2,'second'),
(3,'third')
)
from django.forms import Select
class Select(Select):
def create_option(self, *args,**kwargs):
option = super().create_option(*args,**kwargs)
if not option.get('value'):
option['attrs']['disabled'] = 'disabled'
if option.get('value') == 2:
option['attrs']['disabled'] = 'disabled'
return option
add a comment |
field_choices = (
('','Make choice'),
(1,'first'),
(2,'second'),
(3,'third')
)
from django.forms import Select
class Select(Select):
def create_option(self, *args,**kwargs):
option = super().create_option(*args,**kwargs)
if not option.get('value'):
option['attrs']['disabled'] = 'disabled'
if option.get('value') == 2:
option['attrs']['disabled'] = 'disabled'
return option
field_choices = (
('','Make choice'),
(1,'first'),
(2,'second'),
(3,'third')
)
from django.forms import Select
class Select(Select):
def create_option(self, *args,**kwargs):
option = super().create_option(*args,**kwargs)
if not option.get('value'):
option['attrs']['disabled'] = 'disabled'
if option.get('value') == 2:
option['attrs']['disabled'] = 'disabled'
return option
answered Jul 16 '18 at 20:05
Ivan PetrovIvan Petrov
312 bronze badges
312 bronze badges
add a comment |
add a comment |
Simple questions sometimes have complex answers in Django. I spent a lot of time getting this to work well. Combining Jarrett's overview with an important note from jnns about render_option
and some help from #django on freenode I have a well-working complete example solution:
First, this example assumes a normally defined choices-type CharField in a model I call Rule. I subclass my own TimeStampedModel
but you can use a models.Model
:
class Rule(TimeStampedModel):
...
# Rule Type
SHORT_TERM_RULE = 'ST'
MAX_SIGHTINGS_PER_PERIOD_RULE = "MA"
WHITE_LIST_RULE = "WL"
BLACK_LIST_RULE = "BL"
RULE_CHOICES = (
(SHORT_TERM_RULE, 'Short Term Rule'),
(MAX_SIGHTINGS_PER_PERIOD_RULE, 'Max Sightings Per Period Rule'),
(WHITE_LIST_RULE, 'White List Rule'),
(BLACK_LIST_RULE, 'Black List Rule'),
)
rule_type = models.CharField(
max_length=2,
choices=RULE_CHOICES,
default=SHORT_TERM_RULE,
)
...
In forms.py, define the widget subclassing Select
that accepts disabled_choices
. It has a custom render_option()
that adds disabled
to the html output of option tags if their choice is included on the passed in disabled_choices
list. Note, I left most of the render_option()
code from Select
as-is:
class MySelect(Select):
def __init__(self, attrs=None, choices=(), disabled_choices=()):
super(MySelect, self).__init__(attrs, choices=choices)
self.disabled_choices = disabled_choices
def render_option(self, selected_choices, option_value, option_label):
if option_value is None:
option_value = ''
option_value = force_text(option_value)
if option_value in selected_choices:
selected_html = mark_safe(' selected="selected"')
if not self.allow_multiple_selected:
selected_choices.remove(option_value)
else:
selected_html = ''
for key, value in self.disabled_choices:
if option_value in key:
return format_html('<option disabled value=""></option>', option_value, selected_html,
force_text(option_label))
return format_html('<option value=""></option>', option_value, selected_html, force_text(option_label))
Then, in defining the form subclassing ModelForm
, check for a passed-in disabled_choices
list and initialize the field accordingly. In this example, I also sneak in a default choice.
class RuleChoiceForm(ModelForm):
class Meta:
model = Rule
fields = ['rule_type']
# Add a default choice to the list defined in the Rule model
default_choice = ('DF', 'Choose a Rule Type...')
choices = list(Rule.RULE_CHOICES)
choices.insert(0, default_choice)
choices = tuple(choices)
rule_type = forms.ChoiceField(widget=MySelect(attrs='class': 'form-control', disabled_choices=[]),
choices=choices)
def __init__(self, *args, disabled_choices=None, **kwargs):
super(RuleChoiceForm, self).__init__(*args, **kwargs)
if disabled_choices:
self.fields['rule_type'].widget.disabled_choices = disabled_choices
Then in your view, define disabled_choices
as a list, appending choices from your _CHOICES
var in your model and pass it into the form instantiation. In my logic, I use list comprehension of RULE_CHOICES
to get the tuple of the choice I want to disable. Though there may be a simpler way, please feel free to post suggestions to simplify or improve this answer.
disabled_choices = []
# Logic disabling choices
if Rule.objects.filter(route=route, rule_type=Rule.SHORT_TERM_RULE).exists():
disabled_choices.append([item for item in Rule.RULE_CHOICES if Rule.SHORT_TERM_RULE in item][0])
disabled_choices.append([item for item in Rule.RULE_CHOICES if Rule.MAX_SIGHTINGS_PER_PERIOD_RULE in item][0])
rule_choice_form = RuleChoiceForm(disabled_choices=disabled_choices)
add a comment |
Simple questions sometimes have complex answers in Django. I spent a lot of time getting this to work well. Combining Jarrett's overview with an important note from jnns about render_option
and some help from #django on freenode I have a well-working complete example solution:
First, this example assumes a normally defined choices-type CharField in a model I call Rule. I subclass my own TimeStampedModel
but you can use a models.Model
:
class Rule(TimeStampedModel):
...
# Rule Type
SHORT_TERM_RULE = 'ST'
MAX_SIGHTINGS_PER_PERIOD_RULE = "MA"
WHITE_LIST_RULE = "WL"
BLACK_LIST_RULE = "BL"
RULE_CHOICES = (
(SHORT_TERM_RULE, 'Short Term Rule'),
(MAX_SIGHTINGS_PER_PERIOD_RULE, 'Max Sightings Per Period Rule'),
(WHITE_LIST_RULE, 'White List Rule'),
(BLACK_LIST_RULE, 'Black List Rule'),
)
rule_type = models.CharField(
max_length=2,
choices=RULE_CHOICES,
default=SHORT_TERM_RULE,
)
...
In forms.py, define the widget subclassing Select
that accepts disabled_choices
. It has a custom render_option()
that adds disabled
to the html output of option tags if their choice is included on the passed in disabled_choices
list. Note, I left most of the render_option()
code from Select
as-is:
class MySelect(Select):
def __init__(self, attrs=None, choices=(), disabled_choices=()):
super(MySelect, self).__init__(attrs, choices=choices)
self.disabled_choices = disabled_choices
def render_option(self, selected_choices, option_value, option_label):
if option_value is None:
option_value = ''
option_value = force_text(option_value)
if option_value in selected_choices:
selected_html = mark_safe(' selected="selected"')
if not self.allow_multiple_selected:
selected_choices.remove(option_value)
else:
selected_html = ''
for key, value in self.disabled_choices:
if option_value in key:
return format_html('<option disabled value=""></option>', option_value, selected_html,
force_text(option_label))
return format_html('<option value=""></option>', option_value, selected_html, force_text(option_label))
Then, in defining the form subclassing ModelForm
, check for a passed-in disabled_choices
list and initialize the field accordingly. In this example, I also sneak in a default choice.
class RuleChoiceForm(ModelForm):
class Meta:
model = Rule
fields = ['rule_type']
# Add a default choice to the list defined in the Rule model
default_choice = ('DF', 'Choose a Rule Type...')
choices = list(Rule.RULE_CHOICES)
choices.insert(0, default_choice)
choices = tuple(choices)
rule_type = forms.ChoiceField(widget=MySelect(attrs='class': 'form-control', disabled_choices=[]),
choices=choices)
def __init__(self, *args, disabled_choices=None, **kwargs):
super(RuleChoiceForm, self).__init__(*args, **kwargs)
if disabled_choices:
self.fields['rule_type'].widget.disabled_choices = disabled_choices
Then in your view, define disabled_choices
as a list, appending choices from your _CHOICES
var in your model and pass it into the form instantiation. In my logic, I use list comprehension of RULE_CHOICES
to get the tuple of the choice I want to disable. Though there may be a simpler way, please feel free to post suggestions to simplify or improve this answer.
disabled_choices = []
# Logic disabling choices
if Rule.objects.filter(route=route, rule_type=Rule.SHORT_TERM_RULE).exists():
disabled_choices.append([item for item in Rule.RULE_CHOICES if Rule.SHORT_TERM_RULE in item][0])
disabled_choices.append([item for item in Rule.RULE_CHOICES if Rule.MAX_SIGHTINGS_PER_PERIOD_RULE in item][0])
rule_choice_form = RuleChoiceForm(disabled_choices=disabled_choices)
add a comment |
Simple questions sometimes have complex answers in Django. I spent a lot of time getting this to work well. Combining Jarrett's overview with an important note from jnns about render_option
and some help from #django on freenode I have a well-working complete example solution:
First, this example assumes a normally defined choices-type CharField in a model I call Rule. I subclass my own TimeStampedModel
but you can use a models.Model
:
class Rule(TimeStampedModel):
...
# Rule Type
SHORT_TERM_RULE = 'ST'
MAX_SIGHTINGS_PER_PERIOD_RULE = "MA"
WHITE_LIST_RULE = "WL"
BLACK_LIST_RULE = "BL"
RULE_CHOICES = (
(SHORT_TERM_RULE, 'Short Term Rule'),
(MAX_SIGHTINGS_PER_PERIOD_RULE, 'Max Sightings Per Period Rule'),
(WHITE_LIST_RULE, 'White List Rule'),
(BLACK_LIST_RULE, 'Black List Rule'),
)
rule_type = models.CharField(
max_length=2,
choices=RULE_CHOICES,
default=SHORT_TERM_RULE,
)
...
In forms.py, define the widget subclassing Select
that accepts disabled_choices
. It has a custom render_option()
that adds disabled
to the html output of option tags if their choice is included on the passed in disabled_choices
list. Note, I left most of the render_option()
code from Select
as-is:
class MySelect(Select):
def __init__(self, attrs=None, choices=(), disabled_choices=()):
super(MySelect, self).__init__(attrs, choices=choices)
self.disabled_choices = disabled_choices
def render_option(self, selected_choices, option_value, option_label):
if option_value is None:
option_value = ''
option_value = force_text(option_value)
if option_value in selected_choices:
selected_html = mark_safe(' selected="selected"')
if not self.allow_multiple_selected:
selected_choices.remove(option_value)
else:
selected_html = ''
for key, value in self.disabled_choices:
if option_value in key:
return format_html('<option disabled value=""></option>', option_value, selected_html,
force_text(option_label))
return format_html('<option value=""></option>', option_value, selected_html, force_text(option_label))
Then, in defining the form subclassing ModelForm
, check for a passed-in disabled_choices
list and initialize the field accordingly. In this example, I also sneak in a default choice.
class RuleChoiceForm(ModelForm):
class Meta:
model = Rule
fields = ['rule_type']
# Add a default choice to the list defined in the Rule model
default_choice = ('DF', 'Choose a Rule Type...')
choices = list(Rule.RULE_CHOICES)
choices.insert(0, default_choice)
choices = tuple(choices)
rule_type = forms.ChoiceField(widget=MySelect(attrs='class': 'form-control', disabled_choices=[]),
choices=choices)
def __init__(self, *args, disabled_choices=None, **kwargs):
super(RuleChoiceForm, self).__init__(*args, **kwargs)
if disabled_choices:
self.fields['rule_type'].widget.disabled_choices = disabled_choices
Then in your view, define disabled_choices
as a list, appending choices from your _CHOICES
var in your model and pass it into the form instantiation. In my logic, I use list comprehension of RULE_CHOICES
to get the tuple of the choice I want to disable. Though there may be a simpler way, please feel free to post suggestions to simplify or improve this answer.
disabled_choices = []
# Logic disabling choices
if Rule.objects.filter(route=route, rule_type=Rule.SHORT_TERM_RULE).exists():
disabled_choices.append([item for item in Rule.RULE_CHOICES if Rule.SHORT_TERM_RULE in item][0])
disabled_choices.append([item for item in Rule.RULE_CHOICES if Rule.MAX_SIGHTINGS_PER_PERIOD_RULE in item][0])
rule_choice_form = RuleChoiceForm(disabled_choices=disabled_choices)
Simple questions sometimes have complex answers in Django. I spent a lot of time getting this to work well. Combining Jarrett's overview with an important note from jnns about render_option
and some help from #django on freenode I have a well-working complete example solution:
First, this example assumes a normally defined choices-type CharField in a model I call Rule. I subclass my own TimeStampedModel
but you can use a models.Model
:
class Rule(TimeStampedModel):
...
# Rule Type
SHORT_TERM_RULE = 'ST'
MAX_SIGHTINGS_PER_PERIOD_RULE = "MA"
WHITE_LIST_RULE = "WL"
BLACK_LIST_RULE = "BL"
RULE_CHOICES = (
(SHORT_TERM_RULE, 'Short Term Rule'),
(MAX_SIGHTINGS_PER_PERIOD_RULE, 'Max Sightings Per Period Rule'),
(WHITE_LIST_RULE, 'White List Rule'),
(BLACK_LIST_RULE, 'Black List Rule'),
)
rule_type = models.CharField(
max_length=2,
choices=RULE_CHOICES,
default=SHORT_TERM_RULE,
)
...
In forms.py, define the widget subclassing Select
that accepts disabled_choices
. It has a custom render_option()
that adds disabled
to the html output of option tags if their choice is included on the passed in disabled_choices
list. Note, I left most of the render_option()
code from Select
as-is:
class MySelect(Select):
def __init__(self, attrs=None, choices=(), disabled_choices=()):
super(MySelect, self).__init__(attrs, choices=choices)
self.disabled_choices = disabled_choices
def render_option(self, selected_choices, option_value, option_label):
if option_value is None:
option_value = ''
option_value = force_text(option_value)
if option_value in selected_choices:
selected_html = mark_safe(' selected="selected"')
if not self.allow_multiple_selected:
selected_choices.remove(option_value)
else:
selected_html = ''
for key, value in self.disabled_choices:
if option_value in key:
return format_html('<option disabled value=""></option>', option_value, selected_html,
force_text(option_label))
return format_html('<option value=""></option>', option_value, selected_html, force_text(option_label))
Then, in defining the form subclassing ModelForm
, check for a passed-in disabled_choices
list and initialize the field accordingly. In this example, I also sneak in a default choice.
class RuleChoiceForm(ModelForm):
class Meta:
model = Rule
fields = ['rule_type']
# Add a default choice to the list defined in the Rule model
default_choice = ('DF', 'Choose a Rule Type...')
choices = list(Rule.RULE_CHOICES)
choices.insert(0, default_choice)
choices = tuple(choices)
rule_type = forms.ChoiceField(widget=MySelect(attrs='class': 'form-control', disabled_choices=[]),
choices=choices)
def __init__(self, *args, disabled_choices=None, **kwargs):
super(RuleChoiceForm, self).__init__(*args, **kwargs)
if disabled_choices:
self.fields['rule_type'].widget.disabled_choices = disabled_choices
Then in your view, define disabled_choices
as a list, appending choices from your _CHOICES
var in your model and pass it into the form instantiation. In my logic, I use list comprehension of RULE_CHOICES
to get the tuple of the choice I want to disable. Though there may be a simpler way, please feel free to post suggestions to simplify or improve this answer.
disabled_choices = []
# Logic disabling choices
if Rule.objects.filter(route=route, rule_type=Rule.SHORT_TERM_RULE).exists():
disabled_choices.append([item for item in Rule.RULE_CHOICES if Rule.SHORT_TERM_RULE in item][0])
disabled_choices.append([item for item in Rule.RULE_CHOICES if Rule.MAX_SIGHTINGS_PER_PERIOD_RULE in item][0])
rule_choice_form = RuleChoiceForm(disabled_choices=disabled_choices)
edited Apr 16 at 13:36
answered Mar 26 at 0:09
RobRob
4134 silver badges16 bronze badges
4134 silver badges16 bronze badges
add a comment |
add a comment |
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=(('on', 'On'), ('off', 'Off')))
def __init__(self, request, *args, **kwargs):
if not request.user.is_superuser:
self.fields['status'].widget.disabled_choices = ['off']
super().__init__(*args, **kwargs)
Excuse me I don't understand what is "Status" in "choices=Status.choices()"
– lese
May 24 at 6:22
This is a helper function for managing choice values using IntEnum or Enum types docs.python.org/3/library/enum.html blog post blog.richard.do/2014/02/18/…
– jackotonye
Jun 20 at 16:20
add a comment |
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=(('on', 'On'), ('off', 'Off')))
def __init__(self, request, *args, **kwargs):
if not request.user.is_superuser:
self.fields['status'].widget.disabled_choices = ['off']
super().__init__(*args, **kwargs)
Excuse me I don't understand what is "Status" in "choices=Status.choices()"
– lese
May 24 at 6:22
This is a helper function for managing choice values using IntEnum or Enum types docs.python.org/3/library/enum.html blog post blog.richard.do/2014/02/18/…
– jackotonye
Jun 20 at 16:20
add a comment |
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=(('on', 'On'), ('off', 'Off')))
def __init__(self, request, *args, **kwargs):
if not request.user.is_superuser:
self.fields['status'].widget.disabled_choices = ['off']
super().__init__(*args, **kwargs)
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=(('on', 'On'), ('off', 'Off')))
def __init__(self, request, *args, **kwargs):
if not request.user.is_superuser:
self.fields['status'].widget.disabled_choices = ['off']
super().__init__(*args, **kwargs)
edited Jun 20 at 16:17
answered Apr 30 '18 at 23:09
jackotonyejackotonye
1,81813 silver badges25 bronze badges
1,81813 silver badges25 bronze badges
Excuse me I don't understand what is "Status" in "choices=Status.choices()"
– lese
May 24 at 6:22
This is a helper function for managing choice values using IntEnum or Enum types docs.python.org/3/library/enum.html blog post blog.richard.do/2014/02/18/…
– jackotonye
Jun 20 at 16:20
add a comment |
Excuse me I don't understand what is "Status" in "choices=Status.choices()"
– lese
May 24 at 6:22
This is a helper function for managing choice values using IntEnum or Enum types docs.python.org/3/library/enum.html blog post blog.richard.do/2014/02/18/…
– jackotonye
Jun 20 at 16:20
Excuse me I don't understand what is "Status" in "choices=Status.choices()"
– lese
May 24 at 6:22
Excuse me I don't understand what is "Status" in "choices=Status.choices()"
– lese
May 24 at 6:22
This is a helper function for managing choice values using IntEnum or Enum types docs.python.org/3/library/enum.html blog post blog.richard.do/2014/02/18/…
– jackotonye
Jun 20 at 16:20
This is a helper function for managing choice values using IntEnum or Enum types docs.python.org/3/library/enum.html blog post blog.richard.do/2014/02/18/…
– jackotonye
Jun 20 at 16:20
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f673199%2fdisabled-option-for-choicefield-django%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
This is still an open issue: code.djangoproject.com/ticket/16149
– tobib
May 28 at 15:30