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

怎甘沉沦 提交于 2019-12-20 10:07:22

问题


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?


回答1:


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'),



回答2:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!