Search code examples
djangohttp-redirectregistrationcreate-view

Redirect to previous page after registration in Django


For login and logout, I use Django's built-in view in django.contrib.auth.views. It is very easy to redirect user to previous page because you can pass a 'next' parameter to the login/logout view. They work quit fine.

When I want to fulfill the similar functionality for Registration, there are some problems. It seems that Django doesn't have a built-in registration view. So I'm using the CreateView with 'model=User'. Codes are following:

#views.py

class Registration(CreateView):
    template_name='accounts/registration.html'
    model=User

    #Overwrite form_valid() to log this new user in after his successful registartion
    def form_valid(self, form):
        validation=super(Registration, self).form_valid(form)

        username=form.cleaned_data['username']
        password=form.cleaned_data['password2']
        user=authenticate(username=username, password=password)
        login(self.request, user)

        return validation

Now I don't have a similar 'next' parameter as in the built-in login/logout view. Then how can I redirect the new user to previous page after registration?

I tried the following method:

Step1: From the template which will trigger my Registration view, pass a 'next' parameter via GET method.

<a href="{% url 'accounts:Registration' %}?next={{request.path}}">Registration</a>

By the way, the url related to registration is:

#accounts/urls.py

urlpatterns = patterns('',
    # Others
    url(r'^registration/$', views.Registration.as_view(), name='registration'),
)

Step2: Overwrite the get_context_data() and get_success_url() methods, trying to construct my own 'next' parameter:

#views.py

    class Registration(CreateView):

        # other codes as above

        def get_context_data(self, **kwargs):
              context=super(Registration, self).get_context_data(**kwargs)
              context[next]=self.request.GET['next']
              return context

        def get_success_url(self):
              redirect_to=self.request.POST['next']
              return redirect_to

Step3: In my template, add a 'hidden' input field to hold the next value:

# accounts/registration.html

<form method="post" action="{% url 'accounts:registration' %}" > {% csrf_token %}
    <p>
    {{form.as_p}}
    </p>
    <input type="submit" value="Regsitarte" /> 
    <input type="hidden" name="next" value={{next}} /> 
</form>

This method only works fine when the user doesn't make any mistake during his registration procedure. If, for example, the user POSTs a username which is existing, or the format of the email address is invalid, this method will report an error about the "next" parameter.

Can anyone give a method to redirect a user after registration? Or Can you alter my codes to fulfill this functionality? I'd like to use Django's Built-in Class-based Generic Views, instead of write a new view from scratch.


Solution

  • If you leave a HTML forms action attribute blank it defaults to the URL of the current page, GET query parameters and all.

    If you change your form to remove the hidden field and remove the action it should work fine:

    <form method="post">
        <p>
        {{form.as_p}}
        </p>
        <input type="submit" value="Regsitarte" /> 
    </form>