Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting `django-registration` to send you to the page you were originally trying to visit

django.contrib.auth has an awesome feature: When you try to access a page that's decorated by login_required, you get redirected to the login page with a next argument, so after you login you get redirected back to the page you were originally trying to access. That's good for the user flow.

But, apparently django-registration does not provide a similar feature. I expected that if you register instead of login, you would also get a next thing, and after registering-n'-activating you'll get redirected to the page you were originally trying to visit. This is not the case, you're just redirected to some success page. This hurts the flow.

Does django-registration perhaps provide this option but I'm not using it or correctly? Or is there an easy way to do this?

like image 904
Ram Rachum Avatar asked Oct 28 '11 14:10

Ram Rachum


People also ask

What is Django registration?

django-registration is an extensible application providing user registration functionality for Django-powered Web sites.

How to login in django?

Login Page Django by default will look within a templates folder called registration for auth templates. The login template is called login. html . Create a new directory called templates and within it another directory called registration .

How to logout user in django?

To log out a user who has been logged in via django.contrib.auth.login() , use django.contrib.auth.logout() within your view. It takes an HttpRequest object and has no return value. Example: from django.contrib.auth import logout def logout_view(request): logout(request) # Redirect to a success page.


1 Answers

If you look at the view responsible for the activation of an account via email (registration.views.activate) you'll see that it accepts a success_url parameter which is "The name of a URL pattern to redirect to on successful activation."

So you simply have to overwrite the url that calls that view and provide the page you wish to redirect to.

So in your own urls.py:

from registration.views import activate
urlpatterns = patterns('',
    url(r'^activate/(?P<activation_key>\w+)/$',
            activate,
            {'backend': 'registration.backends.default.DefaultBackend'},
            name='registration_activate',
            # You could use reverse() here instead of a URL to be DRY'er
            success_url = "http://..." 
            ),

Alternatively you could wrap up django-registrations activate view in your own view and accept a GET parameter to redirect to:

from registration.view import activate
def custom_activate(request, backend,
         template_name='registration/activate.html',
         success_url=None, extra_context=None, **kwargs):
    success_url = request.GET.get('next', None)
    return activate(request, template_name=template_name, success_url=success_url, extra_context=None, **kwargs)

Now, in your template registration/activation_email.html you can append the redirection location to the link:

{% url 'registration.view.activate' activation_key as a_url %}

Thanks! ....

{% autoescape off %}
<a href="http://{{ site.domain }}{{ a_url }}?next='http://somepage_or_url'">
    http://{{ site.domain }}{{ url_registration_activate }}/
</a>
{% endautoescape %}

Thanks!

EDIT

Ok, so the above deals with hard coded redirects. I'm guessing this is the flow you want:

  1. User tries to go to a page
  2. User gets redirected to a login/registration page
  3. User signs up on that page and gets sent an email
  4. User activates email and gets redirected to the original page they tried to view

This is more difficult as the page they were trying to view in step one needs to be passed all the way to step four and as we know, HTTP is stateless.

The first suggestion that comes to mind is to save the redirect in a session variable when you register and then retrieve it when you activate. To do this we can overwrite django-registrations default backend (which is just a class with methods that outline the functionality of the registration process and are called from the views), specifically the register and post_activation_redirect methods:

custom_backend.py

from registration.backends.default import DefaultBackend
class RedirectBackend(DefaultBackend):
    def register(self, request, **kwargs):
        request.session['redirect'] = request.GET.get("next",None)
        super(RedirectBackend, self).register(request, **kwargs)

    def post_activation_redirect(self, request, user):
        return(request.session['redirect'], (), {})

and to make sure django-registration actually uses this backend, we provide it to the views via our urls.py:

url(r'^activate/(?P<activation_key>\w+)/$',
    activate,
    {'backend': 'custombackend.RedirectBackend'},
    name='registration_activate'),
url(r'^register/$',
    register,
    {'backend': 'custombackend.RedirectBackend'},
    name='registration_register'),
like image 86
Timmy O'Mahony Avatar answered Oct 09 '22 01:10

Timmy O'Mahony