[Django]-How to process a form (via get or post) using class-based views?

35👍

The default behaviour of the FormView class is to display an unbound form for GET requests, and bind the form for POST (or PUT) requests. If the bound form is valid, then the form_valid method is called, which simply redirects to the success url (defined by the success_url attribute or the get_success_url method.

This matches the example quite well. You need to override the form_valid method to create the new User, before calling the superclass method to redirect to the success url.

class CreateUser(FormView):
    template_name = 'registration/register.html'
    success_url = '/accounts/register/success/'
    form_class = RegistrationForm

    def form_valid(self, form):
        user = User.objects.create_user(
                username=form.cleaned_data['username'],
                password=form.cleaned_data['password1'],
                email=form.cleaned_data['email']
        )
        return super(CreateUser, self).form_valid(form)

Your first example does not match the flow of FormView so well, because you aren’t processing a form with POST data, and you don’t do anything when the form is valid.

I might try extending TemplateView, and putting all the logic in get_context_data.
Once you get that working, you could factor the code that parses the GET data and returns the bookmarks into its own method. You could look at extending ListView, but I don’t think there’s any real advantage unless you want to paginate results.

16👍

Note, an answer here (Updating context data in FormView form_valid method?) solved this problem like this:

class ContextFormView(FormView):
    template_name = 'some_template.html'
    success_url = '...'
    form_class = ClassOfTheForm

    def get(self, request, *args, **kwargs):
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        context = self.get_context_data(**kwargs)
        context['form'] = form
        return self.render_to_response(context)

    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_invalid(self, form, **kwargs):
        context = self.get_context_data(**kwargs)
        context['form'] = form
        # here you can add things like:
        context[show_results] = False
        return self.render_to_response(context)

    def form_valid(self, form, **kwargs):
        context = self.get_context_data(**kwargs)
        context['form'] = form
        # here you can add things like:
        context[show_results] = True
        return self.render_to_response(context)

This worked perfect for me. (same issue as in this question)

As stated above, this is not my solution, if you want to give somebody credits, go to the answer in the link and give this person the credits! (Updating context data in FormView form_valid method?)

Leave a comment