Raman Balyan
Raman Balyan

Reputation: 1063

Retain select option value after submit in Django

I am not using Ajax or django forms. I have plain HTML select tag inside the form tag and sending the selected option value in my view. I want to retain the select option value after the submission. Currently, it comes to default value of 1 irrespective of my selection. Help would be appreciated.

Here is my template code:

            <form method = "post" action = "{% url 'index' %}">
                {% csrf_token %}
                <label class="mainlbl">Vega</label>
                <select name = "drop1" >
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                    <option value="4">4</option>
                    <option value="5">5</option>
                    <option value="6">6</option>
                    <option value="7">7</option>
                    <option value="8">8</option>
                    <option value="9">9</option>
                    <option value="10">10</option>
                    <option value="11">11</option>
                    <option value="12">12</option>
                </select>
                <input class="btn btn-ocean btn-side-bar" type = "submit" value="Submit">
            </form>

Here is my view for that:

def index(request):
    if request.method == "POST":
        vega = request.POST['drop1']
        vega = int(vega)
        gvo = GVOptimize('NSE', 'Nifty')
        data = gvo.get_optimal_strategies(vega)
        str1 = None

        for i in range(0, len(data)):
            if i == 0:
                str1 = data[i]

            elif i == 1:
                str2 = data[i]

            elif i == 2:
                str3 = data[i]

            elif i == 3:
                str4 = data[i]

            else:
                break
        context_dict = {'str1': str1, 'str2': str2, 'str3': str3, 'str4': str4 'vega': vega}
        return render(request, 'demo/dashboard.html', context_dict)
    else:
        context_dict = {}
        return render(request, 'demo/dashboard.html', context_dict)

Upvotes: 4

Views: 5652

Answers (4)

user8234870
user8234870

Reputation:

 <select name = "drop1" >
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
    <option value="7">7</option>
    <option value="8">8</option>
    <option value="9">9</option>
    <option value="10">10</option>
    <option value="11">11</option>
    <option value="12">12</option>
</select>

When you submit the form in views.py you can use

selected_value = request.POST.get("drop1"); // If incase you are using get method which you shouldn't then use request.GET.get("drop1")

Upvotes: 0

Jerzyk
Jerzyk

Reputation: 3752

this answer is here only, because this is not how it should be resolved!

you are using Django, so use Forms that are dedicated for such a use, there are many reasons why to use them, but there are few that matters:

  • simple code
  • straight-forward use of forms with generic views
  • data validation (yes, you do not need to check if this is an integer, or if somebody is hacking your page and posting value outside of range that is in your select)
  • data escape - yes, no more stupid security holes
  • validation tied to form elements, allowing to resubmit data and display to the user where is exactly an error

and don't tell me that this is more work...

forms.py

class MyForm(forms.Form):
    drop1 = forms.IntegerField('Vega', choices=[(x,x) for x in range(1, 13)])

views.py

def index(request):
    context_dict = {}
    if request.method == "POST":
        form = MyForm(data=request.POST)
        if form.is_valid():
            vega = form.cleaned_data['drop1']
            gvo = GVOptimize('NSE', 'Nifty')
            data = gvo.get_optimal_strategies(vega)
            (str1, str2, str3, str4) = data[:4]
            context_dict = {'str1': str1, 'str2': str2,
                            'str3': str3, 'str4': str4 'vega': vega}
    else:
        form = MyForm()

    context_dict['form'] = form

    return render(request, 'demo/dashboard.html', context_dict)

dashboard.html

{% if form.is_valid %}
    <p>Vega: {{ vega }}</p>
{% else %}
<form method="post" action="{% url 'index' %}">{% csrf_token %}
    {{ form }}
    <input class="btn btn-ocean btn-side-bar" type="submit" value="Submit">
</form>
{% endif %}

Upvotes: 1

Abel Barrios
Abel Barrios

Reputation: 1

I am not sure if this is a good practice but you may try creating a function in your view.

def send_selected_combo(self):
    value_from_select = self.request.GET.get('select_html')
    return value_from_select

Then in your template you can call the function.

<select name="select_html" selected="id_selector">
    <option value="combo_value" {%if.view.send_selected_combo=="combo_value"%} selected {%endif%}></option>
</select>

Upvotes: 0

Sayse
Sayse

Reputation: 43300

If you really insist on having a hacky way of maintaining the selected option you can change your form to check every option to see if it equals the number you pass back in your context

<form method = "post" action = "{% url 'index' %}">
    {% csrf_token %}
    <label class="mainlbl">Vega</label>
    <select name = "drop1" >
        {% for idx in "useaformpls!" %}
            <option value="{{ forloop.counter }}" {% if context_val == forloop.counter %}selected {% endif %}>
                 {{ forloop.counter }}
             </option>
        {% endfor %}
    </select>
    <input class="btn btn-ocean btn-side-bar" type = "submit" value="Submit">
</form>

Where context_val equals the index you pass back in the context data of your view.

Upvotes: 2

Related Questions