user8817894
user8817894

Reputation:

Context Variable renders the previous value upon refresh

I have created a form that accepts a file upload and fetches some interesting data from the file upon POST.

However, upon refreshing the page, the form is back to its initial state but the data from the previous file remains. How do I fix it?

Here's my code:

forms.py

choices = (('all', 'all'),
            ('one', 'one'))

class TicketDetailForm(forms.Form):
    file = forms.FileField()
    type = forms.ChoiceField(choices=choices)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

views.py

def home(request):
    detail = []
    if request.method == 'POST':
        form = TicketDetailForm(request.POST, request.FILES)
        if form.is_valid():
            if form.cleaned_data['type'] == 'all':
                file = form.cleaned_data['file'].read()
                detail.append([str(file, 'utf-8')]) 
                # more workaround with the file
    else:
        form = TicketDetailForm()

    return render(request, 'home.html', {'form': form,
                                         'detail': detail})

home.html

{% extends 'base.html' %}

{% block content %}
    <form method="post"  enctype="multipart/form-data">
        {% csrf_token %}
        <p>{{form.as_p}}</p>
        <input type="submit" value="Submit"/>
    </form>

    {% if detail %}
        <div class="row">
            <p>The detail is as follows:</p>
            {% for d in detail %}
                {{ d }}
            {% endif %}
        </div>
    {% endif %}
{% endblock %}

Upvotes: 0

Views: 188

Answers (1)

dirkgroten
dirkgroten

Reputation: 20702

This is because you re-post the form when you refresh the page, since your view just renders the template even if the form is valid. The proper behaviour for a server is to always redirect after successfully submitting a POST. In other words, inside if form.is_valid() you should end by return redirect('home').

Your views should always do the following:

  • For a GET request, render the template
  • For a POST request and invalid form, render the template (with the invalid form so the user can fix errors). Hitting refresh is ok here, it will just re-submit the invalid form and therefore won't cause issues.
  • For a POST request and valid form, redirect, so that the last request is a GET request and the user cannot re-submit when refreshing. This also avoids the valid form to be rendered again.

Upvotes: 1

Related Questions