trouselife
trouselife

Reputation: 969

Django2: After form submission is there a better way to 'wipe' the POST to stop re-submission

I have a django application and on one page I have several forms for different models. I would like a 'success' message, which is easy to do by just adding to the context after form submission/validation. However, this leaves the possibility of re-submission of the form, which would just produce an error back to the page, but it still annoys me.

urls:

 url_patterns = [
      re_path(r'^manager/$', Manager.as_view(), name='manager'),

      .......more.....
 ]

views.py:

class Manager(LoginRequiredMixin, View):

    template_name = 'results/manager_templates/manager.html'
    form1 = Form1
    form2 = Form2

    login_url = '/'
    redirect_field_name = 'redirect_to'


    def get(self, request, *args, **kwargs):

        form1 = self.form1()
        form2 = self.form2()

        context = {
                'form1': form1,
                'form2': form,}

        return render(request, self.template_name, context)


    def post(self, request, *args, **kwargs):

        submit_clicked = request.POST.get('submit')

        form1 = self.form1()
        form2 = self.form2()

        context = {}

        if submit_clicked == 'Form 1':

            form1 = self.form1(request.POST)

            if form1.is_valid():
                form1.save()

                context['message'] = 'Form 1 successful'

                # reset the form
                form1 = self.form1()

                # return HttpResponseRedirect(
                #            reverse('results:manager',
                #        ))


            else:
                print('NOT VALID')


        elif submit_clicked == 'Form 2':

             ... do same stuff as above ...


        context['form1'] = form1
        context['form2'] = form2

        return render(request, self.template_name, context)

If I were to uncomment out the HttpResponseRedirect out, after the form was validated and added like so:

               return HttpResponseRedirect(
                           reverse('results:manager',
                      ))

Then it returns me to my page, and if i refresh the form isnt re-submitted. However I can't pass this an argument without it going through the url:

i.e if I were to write:

               return HttpResponseRedirect(
                           reverse('results:manager',
                           kwargs={'success':'success'}
                      ))

I get the error:

Reverse for 'manager' with keyword arguments '{'success': 'success'}' not found. 1 pattern(s) tried: ['manager/$']

and if I change urls.py to:

 url_patterns = [
        re_path(r'^manager/$', Manager.as_view(), name='manager'),
        re_path(r'^manager/(?P<success>)$', Manager.as_view(), name='manager'),

 ] 

I get the error:

 Reverse for 'manager' with keyword arguments '{'success': 'success'}' not found. 2 pattern(s) tried: ['manager/(?P<success>)$', 'manager/$']

Is there anyway to pass HttpResponseRedirect variables that dont need to be added to url regex? Or is there any other way to 'reset' my request.POST so that forms dont get re-submitted, without using HttpResponseRedirect?

Upvotes: 0

Views: 33

Answers (1)

Alasdair
Alasdair

Reputation: 309049

As you've found, you should redirect after a successful post to prevent duplicate requests.

When you changed the urls, you didn't add any characters to match in your success group.

re_path(r'^manager/(?P<success>\w+)$', Manager.as_view(), name='manager'),

Another option is to store the variable in the querystring, e.g. /manager/?success=success, then you can retrieve the value from request.GET after the redirect.

You could also store data in the session, or use the messages framework.

Upvotes: 1

Related Questions