V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
melaozhu
V2EX  ›  Python

Django写的LoginView,登录成功后无法跳转回原页面,求助!

  •  
  •   melaozhu ·
    laozhu · 2013-10-23 10:33:53 +08:00 · 6941 次点击
    这是一个创建于 4138 天前的主题,其中的信息可能已经有所发展或是发生改变。
    用Django写了个LoginView,可是在登录后跳转上遇到了问题。这句总是获取不到REDIRECT_FIELD_NAME对应的值,以至于无法跳转回之前的页面。

    问题语句:

    redirect_to = self.request.REQUEST.get(REDIRECT_FIELD_NAME, '')

    =============================================

    我的完整代码参见:

    from django.conf import settings
    from django.contrib.auth import login, REDIRECT_FIELD_NAME
    from .forms import LoginForm, ResetPasswordForm
    from django.utils.decorators import method_decorator
    from django.views.generic import FormView
    from django.views.decorators.cache import never_cache
    from django.views.decorators.csrf import csrf_protect
    class LoginView(FormView):
    template_name = 'login.html'
    form_class = LoginForm
    @method_decorator(csrf_protect)
    @method_decorator(never_cache)
    def dispatch(self, *args, **kwargs):
    return super(LoginView, self).dispatch(*args, **kwargs)
    def set_test_cookie(self):
    self.request.session.set_test_cookie()
    def check_and_delete_test_cookie(self):
    if self.request.session.test_cookie_worked():
    self.request.session.delete_test_cookie()
    return True
    return False
    def get(self, request, *args, **kwargs):
    self.set_test_cookie()
    return super(LoginView, self).get(self, request, *args, **kwargs)
    def form_valid(self, form):
    self.check_and_delete_test_cookie()
    login(self.request, form.get_user())
    return super(LoginView, self).form_valid(form)
    def form_invalid(self, form):
    self.set_test_cookie()
    return super(LoginView, self).form_invalid(form)
    def get_context_data(self, **kwargs):
    context = super(LoginView, self).get_context_data(**kwargs)
    context['second_form'] = ResetPasswordForm
    return context
    def get_success_url(self):
    if self.success_url:
    redirect_to = self.success_url
    else:
    # 问题已定位,这里无法获取next的值,求解
    redirect_to = self.request.REQUEST.get(REDIRECT_FIELD_NAME, '')
    host_name = urlparse(redirect_to)[1]
    dir_name = urlparse(redirect_to)[2]
    if not redirect_to:
    redirect_to = settings.LOGIN_REDIRECT_URL
    elif dir_name.lower() == '/logout':
    redirect_to = settings.LOGIN_REDIRECT_URL
    elif host_name and host_name != self.request.get_host():
    redirect_to = settings.LOGIN_REDIRECT_URL
    return redirect_to
    view raw loginview.py hosted with ❤ by GitHub


    参照了这个项目:

    https://github.com/stefanfoulis/django-class-based-auth-views

    顺带问下,如果希望对于已登录用户不显示登录表单,而是直接redirect到主页,我的代码需要做怎样的修改。求各路大婶出手相助。
    8 条回复    1970-01-01 08:00:00 +08:00
    melaozhu
        1
    melaozhu  
    OP
       2013-10-23 10:43:54 +08:00
    这样的URL

    http://mydomain.com/login?next=/admin/staff

    登录后不能跳转回

    http://mydomain.com/admin/staff


    没人在啊。。。


    会不会是我的urls.py定义有问题

    url(
    regex = r'^login$',
    view = LoginView.as_view(),
    name = 'login'
    ),

    我是这样定义的。
    aggron
        2
    aggron  
       2013-10-23 11:07:29 +08:00   ❤️ 1
    已登录用户不显示登录表单,在get方法里面加
    if request.user.is_authenticated():
    return redirect('/')

    REDIRECT_FIELD_NAME 默认应该就是获取URL中的`next` parameter,按照你给的URL格式应该是没问题的,或许你看下LoginForm中的代码有没redirect之类的代码。
    你贴的urls.py是全的吗,没看到/admin/staff相关的定义
    melaozhu
        3
    melaozhu  
    OP
       2013-10-23 11:22:31 +08:00
    不好意思,还有一部分没贴。

    # urls.py
    urlpatterns = patterns('',
    url(r'^admin/staff', include('auth2.urls')),
    )

    # auth2/urls.py
    urlpatterns = patterns('',
    url(
    regex = r'^$',
    view = StaffListView.as_view(),
    name = 'staff-list',
    ),
    )

    我现在就是没法获取到next后面的地址,我是这样定义的
    from django.contrib.auth.forms import AuthenticationForm
    class LoginForm(AuthenticationForm):
    error_messages = {}
    username = {}
    password = {}
    只是冲定义了这三个东西,其它函数未动,貌似AuthenticationForm中只没有redirect之类语句。

    我现在怀疑get_success_url()函数中是否可以获取到REDIRECT_FIELD_NAME的值。
    melaozhu
        4
    melaozhu  
    OP
       2013-10-23 11:37:07 +08:00
    @aggron 兄才
    from django.core.urlresolvers import reverse
    def get(self, request, *args, **kwargs):
    self.set_test_cookie()
    if self.request.user.is_authenticated:
    return reverse('home')
    return super(LoginView, self).get(self, request, *args, **kwargs)

    我加了这段后,报错了。。。
    Exception Type: AttributeError
    Exception Value:
    'str' object has no attribute 'has_header'
    aggron
        5
    aggron  
       2013-10-23 11:41:38 +08:00
    reverse 返回的只是一个str类型的url
    应该用return redirect(reverse('home'))
    melaozhu
        6
    melaozhu  
    OP
       2013-10-23 11:45:00 +08:00
    @aggron 这下对了,非常感谢!
    aggron
        7
    aggron  
       2013-10-23 13:46:14 +08:00
    BTW: is_authenticated是个方法,不是property,要用user.is_authenticated():
    daoluan
        8
    daoluan  
       2013-10-23 15:36:49 +08:00
    重定向回去就好了. redirect
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2862 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 14:47 · PVG 22:47 · LAX 06:47 · JFK 09:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.