How do I get the text value of a selected option in django views.py
Question:
For example: if first option Regular is selected then how can i get the value “1” and its text value “Regular” in views.py
<form method = "post" action = "{% url 'index' %}">
{% csrf_token %}
<select name = "drop1" >
<option value="1">Regular</option>
<option value="2">Medium</option>
<option value="3">Large</option>
</select>
<input type = "submit" value="Submit">
Answers:
The value 1
should be in request.POST
under the key drop1
.
This should help you see the selected value in your view:
print(request.POST['drop1'])
The text content of the <option>
tag is not submitted to your view, only the text inside the value
attribute. This is a HTML and web browser design; Python or Django do not control what gets sent in a POST request.
If you really need to get both strings (1
and Regular
) in the POST request, one workaround I have used in the past was to duplicate the text in the HTML tag
<option value"1-Regular">Regular</option>
so that the value 1-Regular
gets sent; then I did split the string in the view
v1, v2 = request.POST['drop1'].split('-')
print(v1)
print(v2)
It is not a perfect solution, but it did work for me.
Another solution (also without using Django forms) I can think of is to use a Python dict
(or list
) to hold all your options in your view:
import collections
DROP1_DICT = collections.OrderedDict(
(1, 'Regular'),
(2, 'Medium'),
)
def my_view(request):
...
if request.method == 'POST':
selected_value = request.POST['drop1']
selected_label = DROP1_DICT[selected_value]
print(selected_value)
print(selected_label)
else:
ctx = {
'drop1_dict': DROP1_DICT,
}
return render(request, 'my_template.html', ctx)
and render the template based on that:
<form method = "post" action = "{% url 'index' %}">
{% csrf_token %}
<select name = "drop1" >
{% for k, v in drop1_dict.items %}
<option value="{{ k }}">{{ v }}</option>
{% endfor %}
</select>
<input type="submit" value="Submit">
</form>
Of course, if you simply use a django form for this then all the underlying handling is done for you and you can just skip this part of the code.
If anyone stuck at same scenario and the choice options are from backend, can use to_field_name
attribute of ModelChoiceField
. Say if the Regular, Medium, and Large are the choices of a field called size
in ProductSize
model, try forms as follows:
class SearchForm(forms.Form):
size = forms.ModelChoiceField(
queryset=ProductSize.objects.all(),
to_field_name="size",
widget=forms.Select(attrs={"class": "form-control"}),
empty_label="Choose")
above form will render choices in html as:
<select name="size" class="form-control select form-select" required="" id="id_size">
<option value="" selected="">Choose</option>
<option value="Regular">Regular</option>
<option value="Medium">Medium</option>
<option value="Large">Large</option>
</select>
You can simply get these values in views.py by self.request.POST.get("size")
.
See docs
Better to use Django Forms, then you could do something like this in your view:
if request.method == 'POST':
# print number value
print(request.POST.get('your_select_field'))
form = YourForm(request.POST)
# print number value
print(form['your_select_field'].value())
if form.is_valid():
# print text value
print(form.cleaned_data['your_select_field'])
drop = form.save(commit=False)
# print text value
print(drop.your_select_field)
For example: if first option Regular is selected then how can i get the value “1” and its text value “Regular” in views.py
<form method = "post" action = "{% url 'index' %}">
{% csrf_token %}
<select name = "drop1" >
<option value="1">Regular</option>
<option value="2">Medium</option>
<option value="3">Large</option>
</select>
<input type = "submit" value="Submit">
The value 1
should be in request.POST
under the key drop1
.
This should help you see the selected value in your view:
print(request.POST['drop1'])
The text content of the <option>
tag is not submitted to your view, only the text inside the value
attribute. This is a HTML and web browser design; Python or Django do not control what gets sent in a POST request.
If you really need to get both strings (1
and Regular
) in the POST request, one workaround I have used in the past was to duplicate the text in the HTML tag
<option value"1-Regular">Regular</option>
so that the value 1-Regular
gets sent; then I did split the string in the view
v1, v2 = request.POST['drop1'].split('-')
print(v1)
print(v2)
It is not a perfect solution, but it did work for me.
Another solution (also without using Django forms) I can think of is to use a Python dict
(or list
) to hold all your options in your view:
import collections
DROP1_DICT = collections.OrderedDict(
(1, 'Regular'),
(2, 'Medium'),
)
def my_view(request):
...
if request.method == 'POST':
selected_value = request.POST['drop1']
selected_label = DROP1_DICT[selected_value]
print(selected_value)
print(selected_label)
else:
ctx = {
'drop1_dict': DROP1_DICT,
}
return render(request, 'my_template.html', ctx)
and render the template based on that:
<form method = "post" action = "{% url 'index' %}">
{% csrf_token %}
<select name = "drop1" >
{% for k, v in drop1_dict.items %}
<option value="{{ k }}">{{ v }}</option>
{% endfor %}
</select>
<input type="submit" value="Submit">
</form>
Of course, if you simply use a django form for this then all the underlying handling is done for you and you can just skip this part of the code.
If anyone stuck at same scenario and the choice options are from backend, can use to_field_name
attribute of ModelChoiceField
. Say if the Regular, Medium, and Large are the choices of a field called size
in ProductSize
model, try forms as follows:
class SearchForm(forms.Form):
size = forms.ModelChoiceField(
queryset=ProductSize.objects.all(),
to_field_name="size",
widget=forms.Select(attrs={"class": "form-control"}),
empty_label="Choose")
above form will render choices in html as:
<select name="size" class="form-control select form-select" required="" id="id_size">
<option value="" selected="">Choose</option>
<option value="Regular">Regular</option>
<option value="Medium">Medium</option>
<option value="Large">Large</option>
</select>
You can simply get these values in views.py by self.request.POST.get("size")
.
See docs
Better to use Django Forms, then you could do something like this in your view:
if request.method == 'POST':
# print number value
print(request.POST.get('your_select_field'))
form = YourForm(request.POST)
# print number value
print(form['your_select_field'].value())
if form.is_valid():
# print text value
print(form.cleaned_data['your_select_field'])
drop = form.save(commit=False)
# print text value
print(drop.your_select_field)