Lucretiel
Lucretiel

Reputation: 3324

How to access form data in `FormView.get_success_url()`

Currently, I have a form that looks like this:

class SelectBoard(generic.FormView):
    form_class = forms.SelectBoard

    def form_valid(self, form):
        board_name = form.cleaned_data['name']
        return redirect('leaderboard', board_name=board_name)

However, it would be my preference to do the more idiomatic thing, and use get_success_url. Something like this:

class SelectBoard(generic.FormView):
    form_class = forms.SelectBoard

    def get_success_url(self):
        form = ???
        board_name = form.cleaned_data['name']
        return reverse('leaderboard', board_name=board_name)

However, the form is not passed to get_success_url, and unlike many other pieces of request context (like self.request, self.kwargs, or self.object (in DetailView)), the form is not attached as an attribute at any point in the standard FormView dispatch sequence. Is there any good way to access cleaned & validated form data in get_success_url (that is, without having to access self.request.POST or reconstruct the form from scratch)?

Upvotes: 15

Views: 4856

Answers (2)

Rafael Maciel
Rafael Maciel

Reputation: 145

You might set the success_url attribute in form_valid method getting the form field value if it is needed

class SelectBoard(generic.FormView):
    form_class = forms.SelectBoard

    def form_valid(self, form):
        board_name = form.cleaned_data['name']
        self.success_url = reverse('leaderboard', board_name=board_name)

        return super().form_valid(form)

Upvotes: 0

neverwalkaloner
neverwalkaloner

Reputation: 47354

You can override form_valid method to write form as instance attribute and use self.form inside get_success_url:

class SelectBoard(generic.FormView):
    form_class = forms.SelectBoard

    def form_valid(self, form):
        """If the form is valid, redirect to the supplied URL."""
        self.form = form    
        return HttpResponseRedirect(self.get_success_url())

    def get_success_url(self):
        board_name = self.form.cleaned_data['name']
        return reverse('leaderboard', board_name=board_name)

Upvotes: 12

Related Questions