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?
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:
- User tries to go to a page
- User gets redirected to a login/registration page
- User signs up on that page and gets sent an email
- 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'),
You should use the same decorator @login_required, django-registration uses that too.
来源:https://stackoverflow.com/questions/7930526/getting-django-registration-to-send-you-to-the-page-you-were-originally-trying