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">
Asked By: M_FarhanZia

||

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.

Answered By: Ralf

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.

Answered By: Ralf

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

Answered By: Muhammmed Nihad

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)
Answered By: Jan Lněnička
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.