Kiran
Kiran

Reputation: 1531

How to retain select option value after submit in django?

I have created select tag with four option values(1,2,3,4).When I select 4 and press submit it changes back to 1.Select option contains quantity of the product needed for the user.So how to retain option value after pressing submit button.I tried like this,after I press submit button value changes back to 1.Is there any way to overcome this problem?

My template file,

<label for="quantity">Quantity</label>
            <select id="quantity" name="quantity">
                <option value="1" {% if quantity == '1' %}selected{% endif %}>1</option>
                <option value="2" {% if quantity == '2' %}selected{% endif %}>2</option>
                <option value="3" {% if quantity == '3' %}selected{% endif %}>3</option>
                <option value="4" {% if quantity == '4' %}selected{% endif %}>4</option>
            </select>  
<input type="submit" value="Buy"/>

UPDATE: forms.py,

class SortForm(forms.Form):
     RELEVANCE_CHOICES = (
                    (1,'1'),(2, '2'),(3,'3'), (4,'4'),(5,'5'),
     )
     sort = forms.ChoiceField(choices = RELEVANCE_CHOICES,label='Quantity')

views.py,

from .forms import SortForm
@csrf_protect
def buy_book(request,pk):
    form = SortForm(request.POST or None)
    my_products = Add_prod.objects.filter(pk=pk)
    #Add_prod is the model class name
    context = {"products":my_products}

    if request.POST.get('quantity'):
        for i in my_products:
            rate= i.price
        #price is the column name in the model class
        u_quantity = request.POST.get('quantity')
        Quantity=int(u_quantity)
        total = rate*Quantity
        context = {    
                "products":my_products,
                "Total":total,
                "form": form         
        }    
    return render(request,"buy_book.html",context)

In the template file I added this line,

{{form.as_p}}

Now I am getting blank output.I think the form is not recognising in the template.

Upvotes: 1

Views: 4345

Answers (2)

Sardorbek Imomaliev
Sardorbek Imomaliev

Reputation: 15400

The problem here that your template is just showing data, it doesn't know anything about state. So if you want to achieve this kind of behavior you need to supply all required data from backend. Also as @solarissmoke mentioned you should use django forms.

for exmaple(Pseudo code below)

def my_view(request):
    if request.method == 'POST':
        form = MyForm(request.data)
        if form.is_valid():
            form.save()
            redirect(reverse('myview'))
    else:
        form = MyForm(instance) # <- instance is object with previously saved data
    return render(request, 'my_template.html' , {'form': form})

Second Part

def buy_book(request,pk):
    form = SortForm(request.POST or None)
    my_products = Add_prod.objects.filter(pk=pk)
    #Add_prod is the model class name
    context = {"products":my_products}

    if request.POST.get('quantity'):
        for i in my_products:
            rate= i.price
        #price is the column name in the model class
        u_quantity = request.POST.get('quantity')
        Quantity=int(u_quantity)
        total = rate*Quantity
        context = {    
            "products":my_products,
            "Total":total,
            "form": form        # <- here is problem 
        }    
    return render(request,"buy_book.html",context)

You are adding form to context inside if request.method == 'POST'. It should like this

def buy_book(request,pk):
    form = SortForm(request.POST or None)
    my_products = Add_prod.objects.filter(pk=pk)
    #Add_prod is the model class name
    context = {"products":my_products, 'form': form} # <- here

    if request.POST.get('quantity'):
        for i in my_products:
            rate= i.price
        #price is the column name in the model class
        u_quantity = request.POST.get('quantity')
        Quantity=int(u_quantity)
        total = rate*Quantity
        context = {    
            "products":my_products,
            "Total":total,
        }    
    return render(request,"buy_book.html",context)

Upvotes: 2

Sayse
Sayse

Reputation: 43330

In your view, you only ever add the form to the context data if there is a quantity in the post data, you should add this to the context regardless since it is required for your view.

You should also actually use the form, so instead of checking the post data, check the form for validity and then use its cleaned data.

def buy_book(request,pk):
    form = SortForm(request.POST or None)
    my_products = Add_prod.objects.filter(pk=pk)
    #Add_prod is the model class name
    context = {"products":my_products,
               'form': form}

    if form.is_valid():
        for i in my_products:
            rate= i.price
        #price is the column name in the model class
        u_quantity = form.cleaned_data.get('sort', 0)
        Quantity=int(u_quantity)
        total = rate*Quantity
        context['total'] = total
    return render(request,"buy_book.html",context)

'int' object is not iterable

Probably because your sort field isn't a list of tuples

choices = [(i, i) for i in range(1,6)]

Upvotes: 1

Related Questions