7

I have made a form where i wish to return to the same form again, this time with context data that can be used in my template to show that the form has been successfully sent.

How can i do this?

class ContactUsView(FormView):
    form_class = ContactUsForm
    template_name = 'website/pages/contact_us.html'

    def form_valid(self, form):
        form.send_email()
        return super(ContactUsView, self).form_valid(form)

    def get_success_url(self):
        # Something here?

So basically i want get_success_url to return to the ContactUsView with e.g. {'success':'true'} which i can read in the template and render a box that says it has been successfull. I dont want to change to another static page!

JavaCake
  • 4,075
  • 14
  • 62
  • 125
  • try this `return reverse('url_name', kwargs={'pk': pk})` – Hasan Ramezani Oct 21 '14 at 09:24
  • I did not exactly want to pass a kwarg as i then will have to alter my url pattern for that page. That seems a little overkill. I just want to pass some variable to context instead. If i use your method it wont work straight away in any case without altering things: `Reverse for 'ContactUsView' with arguments '()' and keyword arguments '{'pk': '12'}' not found. 1 pattern(s) tried: ['contact/$']` – JavaCake Oct 21 '14 at 09:43
  • you can use a optional parameter in url for this case. give your `urls.py`. – Hasan Ramezani Oct 21 '14 at 09:59
  • url(r'^contact/$', ContactUsView.as_view(), name="ContactUsView"), – JavaCake Oct 21 '14 at 10:00
  • add a url like this : `url(r'^contact/(?P\w+)$', ContactUsView.as_view(), name="ContactUsView"),` and change your view like this : `def ContactUsView(success=None):` – Hasan Ramezani Oct 21 '14 at 10:05
  • Is it possible to do the same with class-based views? – JavaCake Oct 21 '14 at 10:09
  • take a look at [this](http://stackoverflow.com/questions/11494483/django-class-based-view-how-do-i-pass-additional-parameters-to-the-as-view-meth). may help you about `class-based` view. – Hasan Ramezani Oct 21 '14 at 10:14

2 Answers2

4

add a url like this to urls.py:

url(r'^contact/(?P<success>\w+)$', ContactUsView.as_view(), name="ContactUsView"),

And you can access to this parameter in class-based view like this:

add get_context_data method to your class-view

class ContactUsView(DetailView):
    context_object_name = 'my_var'

    def get_context_data(self, **kwargs):
        context = super(ContactUsView, self).get_context_data(**kwargs)
        context['success'] = self.success
        return context

And you can use {{ my_var.success }} in your template.

Amandeep Singh
  • 1,371
  • 1
  • 11
  • 33
Hasan Ramezani
  • 5,004
  • 24
  • 30
3

The success_url approach uses a redirect, which implies you need to pass any additional context data as url parameters, as described in hasan-ramezani's answer.

An alternative would be not to use success_url at all:

Instead, you could override form_valid() so it returns a TemplateResponse instead of an HTTPResponseRedirect, following the example of form_invalid(). Something similar is described here.

This way, there is no need to modify your urls.py.

For example:

class ContactUsView(FormView):
    form_class = ContactUsForm
    template_name = 'website/pages/contact_us.html'

    def form_valid(self, form):
        """Render the form again, with current form data and custom context."""
        context = self.get_context_data(form=form)
        context['success'] = True
        context['whatever'] = 'some other custom context'
        return self.render_to_response(context=context)
djvg
  • 11,722
  • 5
  • 72
  • 103