I have a Django choice form:
SEASON_CHOICES = (
('running', 'Running season'),
('next', 'Next season' )
)
class DeterminingForm(forms.Form):
season = forms.ChoiceField(widget=forms.Select, choices=SEASON_CHOICES)
I want a disabled option in my form. Something like a placeholder with 'Choose an option', just like you see on almost any select form. I don't know how to do this. Any idea?
Related
So I have a user model with the following columns:
username = models.CharField(db_column='Username',max_length=32,unique=True)
email = models.CharField(db_column='Email',max_length=255)
password = models.CharField(db_column='Password',max_length=128)
prosthodontist = models.ForeignKey('Prosthodontist',on_delete=models.SET_NULL,null=True)
I'm trying to make a dropdown that allows the user to change their Prosthodontist value through django forms. It can't be a static list cause it has to always have every available Prosthodontist as they get added.
Just for show this is what I have so far along the lines of the form:
class ChangeProsthodontistForm(forms.ModelForm):
class Meta:
model = User
fields = ('prosthodontist',)
prosthodontist = forms.ChoiceField(
label = "Prosthodontist",
widget = forms.Select(
attrs={
'id':'prosthodontist',
},
),
choices=()
)
Please help me with this cause I'm really confused I feel like I could be able to iterate through the entries with a for loop but I feel like there has to be a better way through Django.
You answer is ModelChoiceField.
prosthodontist = forms.ModelChoiceField(
# ...
queryset = Prosthodontist.objects.all(),
# ...
)
I am a complete beginner with little understanding of widgets etc, I'm using a model-based form that needs to have a drop-down selection box for dietary preferences. this is what I tried to do earlier (obviously wrong):
class Register(models.Model):
dietry_preferences = forms.ModelChoiceField( queryset = "none", "vegetarian", "vegan", "halaal", "kosher", empty_label = "none")
can anyone shed some light on this?
ModelChoiceField is related to forms. It is unclear if you want to build a form or a model. Therefore, for a model:
class Register(models.Model):
PREFERENCES = (
('vt', "vegetarian"),
('vg', "vegan"),
....
)
dietry_preferences = models.CharField(max_length=5, choices=PREFERENCES)
Then you would build a modelform appropriately.
Reference: Django documentation, choices
Otherwise, for a form:
class Register(forms.Form):
PREFERENCES = (
('vt', "vegetarian"),
('vg', "vegan"),
....
)
dietry_preferences = forms.ChoiceField(choices=PREFERENCES)
Reference: Django documentation, ChoiceField
Following the django documentation I try to make a choices field in my
models.py:
class MyModel(Model):
ACTION_CHOICES = (
('d', 'delete'),
('c', 'create'),
('u', 'update'),
)
action = CharField(max_length=1, choices=ACTION_CHOICES)
But when I run it with
action = MyModel(action='create')
action.save()
and check the database the action is not c, but create. Furthermore even restriction to max_length doesn't affect on it. Ok, I moved on and tried to make it in this way:
models.py
class MyModel(Model):
ACTION_CHOICES = (
(1, 'delete'),
(2, 'create'),
(3, 'update'),
)
action = IntegerField(max_length=1, choices=ACTION_CHOICES)
code.py:
action = MyModel(action='create')
action.save()
But I got an error that str field can't be saved like int (database has the int field, but MyModel.action is str) What Do I miss here? Aren't choices supposed to convert value on save?
Best regards,
There are several questions in your post:
1) The choices can only restrict what can be entered through a Django form. When you manually instantiate your object you can insert any value. So
action = MyModel(action='create')
actually inserts the string create into the action column.
2) Normally max_length should stop you from inserting a string longer than 1 character into that column, but I guess you are using SQLite which has no restriction on VARCHAR lengths.
3) Django has no easy conversion from the display values to choice keys. You can have a look at django-model-utils for a wrapper on choices.
When you define choices
ACTION_CHOICES = (
(1, 'delete'),
(2, 'create'),
(3, 'update'),
)
the values stored in the db are 1, 2, 3, while 'delete', 'create' etc.. are just labels, just to explain, the prev choices results in such select input element:
<select>
<option value="1">delete</option>
<option value="2">create</option>
<option value="3">update</option>
</select>
Choices are not supposed to convert value on save, are supposed to map db values with labels, and used when rendering the form widget and when retrieving the field representation (get_field_display). But if you set directly the value of a column it doesn't play a role.
If you want to use "talking keys" you can define them as class properties, like
class MyModel(models.Model):
DELETE_ACTION = 1
CREATE_ACTION = 2
UPDATE_ACTION = 3
ACTION_CHOICES = (
(DELETE_ACTION, 'delete'),
(CREATE_ACTION, 'create'),
(UPDATE_ACTION, 'update'),
)
Then you can do
action = MyModel(action=MyModel.CREATE_ACTION)
and it would be fine
In my application,i am keeping some choices in forms.The choices are check box input and user can click and save the choices.In database saved choice are stored as integer like 1,2,3.How to query the saved value from database and show it in template as their corresponding options.
forms.py
OPTIONS = (
('1', 'Today'),
('2', 'This Week'),
('3', 'This Month'),
('4', 'This Year'),
('5', 'All'),
)
class ReporForm(forms.ModelForm):
optons = forms.ChoiceField(widget=forms.Select(), choices=OPTIONS,required=False, initial=0)
template
{{ reportform.as_p}}
Here,if user selected "This week" as their option,then in database the value of "This week" "2" will be saved.
In usual if i query the data from table,it is rendering the value as "2".But i want it to display "This week" in template.I don't see any tutorial or blog in this way.
I don't know how to do this in Django.
In order to retrieve the value of your dictionary in django, you can use the following syntax:
ReporForm.get_optons_display()
So for example, if you wanted to check if the database query was 'All' or the key '5' you could simply do:
if ReporForm.get_optons_display() == 'ALL':
#do something
Django Docs
An excerpt for an example:
Views.py
#Query your database to retrieve your instance of 'ReporForm'
#I will assume there is a primary key of some type (Reportcode)
foo = ReporForm.objects.get(ReportCode = 1234)
#Pass foo to the context
context = {'foo':foo}
#Send this context to your render_to_response so it goes to template
reportform.html
<b>You have selected the option :</b> '{{ foo.get_optons_display }}'
I have a form with a choice field that is using CheckboxSelectMultiple widget:
foo = forms.ChoiceField(widget=forms.CheckboxSelectMultiple,
choices=(
("1", "ONE"),
("2", "TWO"),
))
The form renders fine showing two checkboxes, however it doesn't validate.
If I select both checkboxes I am getting an error: Select a valid choice. [u'1', u'2'] is not one of the available choices
Selecting one checkbox doesn't work either, it gives me: Select a valid choice. [u'1'] is not one of the available choices.
What's going on here?
If you make the field a forms.MultipleChoiceField rather than a forms.ChoiceField it will work better.
May this helpful for you
num_choices = ( ("1", "ONE"), ("2", "TWO"), ("3", "Three"), ("4", "Four"))
num_list = forms.MultipleChoiceField(choices=num_choices, required=True, widget=forms.CheckboxSelectMultiple(), label='Select No', initial=("1", "2"))
If you want to pass the ORM object directly, then you can try the following
num_list = forms.ModelMultipleChoiceField(Numbers.objects.all(), required=True, widget=forms.CheckboxSelectMultiple(), label='Select No')