0

In my app, I want the following behaviour:

  1. User goes to contact form url
  2. User fills up the contact form
  3. (a) If user is logged in, validate and submit the form
  4. (b) If user is not logged in, redirect to login form for logging in and then if users credentials are validated, submit the form.

In my views.py, I have:

@method_decorator(login_required, name='post')
class ContactView(FormView):
    template_name = 'extras/contact.html'
    form_class = ContactForm

def post(self, request, *args, **kwargs):
    form_class = self.get_form_class()
    form = self.get_form(form_class)
    if form.is_valid():
        return self.form_valid(form, **kwargs)
    else:
        return self.form_invalid(form, **kwargs)

def form_valid(self, form):
    instance = form.instance
    instance.request_user = self.request.user
    instance.save()
    messages.success(self.request, "Thank you for contacting us! We will reach you soon.")
    return super().form_valid(form)

def get_success_url(self):
    return reverse('main_home')

The idea of including a post method was taken from this SO Answer

This does not work. The user is being redirected to login form, logged in, but displays a blank form and entered information before redirection is lost.

How can I resolve this problem, any hints?

inquilabee
  • 713
  • 1
  • 11
  • 23
  • 1
    It’s not usually a good idea to override the `get` or `post` methods for generic class based views, because you can either break functionality or have to duplicate code. In your case, the `post` method doesn’t seem to do anything different to the `FormView`’s post method, so I would remove it. – Alasdair May 10 '18 at 12:15
  • @Alasdair, I agree. I just included to to apply a login_required decorator to it which was not working without including. Or I might not have tested it well enough. – inquilabee May 10 '18 at 12:17
  • 1
    Since you use `method_decorator`, you don’t have to override `post` to decorate it. But if you did, you could call `super().post(request, *args, **kwargs)` to prevent duplication. – Alasdair May 10 '18 at 12:20

1 Answers1

1

When you redirect a post request to the login page, you’ll lose the post data. Therefore you should redirect GET requests as well, so that the user logs in before they fill out the contact form. You can do this by decorating the dispatch method.

@method_decorator(login_required, name='dispatch')
class ContactView(FormView):
Alasdair
  • 298,606
  • 55
  • 578
  • 516