After submiting data via form you keep getting this annoying ‘Confirm Form Resubmission’ alert from Google Chrome? Here is the solution.
Sidenote: this specific example of clearing POST data uses a simple html form and a class-based view.
So here is the offending message:

No more resubmission
In post() function instead of render:
from django.views.generic import TemplateView
from django.shortcuts import render
class CoolView(TemplateView):
def post(self, request, *args, **kwargs):
''' Anything you need '''
return render(request, template_name, context)
use HttpResponseRedirect():
from django.views.generic import TemplateView
from django.http import HttpResponseRedirect
class CoolView(TemplateView):
def post(self, request, *args, **kwargs):
''' Anything you need '''
return HttpResponseRedirect(request.path)
Refresh the page and voila! Everything is perfect. Or is it?..
Success Message
In order to somehow tell the user that the form is successfully (or not) processed, I will send them a message (e.g. a dismissable banner is a good practice).
If you use context[‘messages’], delete it and use django.contrib.messages instead.
from django.views.generic import TemplateView
from django.http import HttpResponseRedirect
from django.contrib import messages
class CoolView(TemplateView):
def post(self, request, *args, **kwargs):
''' Anything you need '''
messages.success(request, 'Success!')
return HttpResponseRedirect(request.path)
In order to set a message in post() set the message:
To work with messages on the template use this (where message.tag is ‘success’) iteration of all of the messages in session right now:
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class=""{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
If you are using this thing with only immediate interactions, you will be fine. E.g. for Celery, I would recommend models.
But now the messages are stacked. And I used this with other forms. Soon the list of messages is higher than the Empire State! Oops… So to resolve this, in get() clear it:
from django.views.generic import TemplateView
from django.contrib import messages
class CoolView(TemplateView):
def get(self, request, *args, **kwargs):
system_messages = messages.get_messages(request)
for message in system_messages:
pass
system_messages.used = True
return render(request, self.template_name, self.context)
This way the messages array will only have one message. What a beauty!
Context
If, by chance, you need to pass some extra context data to the template, with HttpResponseRedirect you need to use:
request.session['other_data'] = 'wow'
Just add it somewhere, like this:
from django.views.generic import TemplateView
from django.http import HttpResponseRedirect
from django.contrib import messages
class CoolView(TemplateView):
def post(self, request, *args, **kwargs):
''' Anything you need '''
messages.success(request, 'Success!')
request.session['other_data'] = 'wow'
return HttpResponseRedirect(request.path)
If you keep it like that, even after reloading the page, this context data will remain on the page. I am in the process of figuring out how to fix that. (edit 13.10.2019)
Thank you for your attention.
This post was born with the help of awesome people on StackOverFlow (one and two).