登录表单后的HttpResponseRedirect不会重定向到配置文件

时间:2017-07-08 03:31:58

标签: django

我试图让Django网站的本地副本正常工作。生产站点在登录时工作正常,但我的本地实例在完成登录表单后没有重定向到配置文件页面。

这是login_page视图:

def login_page(request):
  profile_page = HttpResponseRedirect('profile')
  if request.user.is_authenticated():
    return profile_page
  form = LoginForm(request.POST or None)
  if request.POST and form.is_valid():
    user = form.login(request)

    if user:
      login(request, user)
      return profile_page

  return render(request, 'login.html', {'form': form})

这是服务器的调试输出显示的内容:

Performing system checks...

<function home_page at 0x7f77ad696c08>
System check identified no issues (0 silenced).
July 08, 2017 - 03:21:39
Django version 1.9.1, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[08/Jul/2017 03:21:49] "GET / HTTP/1.1" 200 3276
[08/Jul/2017 03:21:50] "GET /login HTTP/1.1" 200 2370
[08/Jul/2017 03:21:57] "POST /login HTTP/1.1" 302 0
[08/Jul/2017 03:21:57] "GET /profile HTTP/1.1" 302 0
[08/Jul/2017 03:21:57] "GET /login?next=/profile HTTP/1.1" 200 2370

完成上述操作后,浏览器将保留在http://127.0.0.1:8000/login?next=/profile,只显示标准登录页面。

同样,相同的代码在生产中使用相同版本的Django(虽然通过gunicorn / nginx而不是django-admin runserver运行),所以它让我觉得我的Django配置中有一些东西我错过了而不是实际的代码问题。

urls.py条目:

from accounts import urls as account_urls
...
  url(r'^', include(account_urls)),

账户/ urls.py:

from django.conf.urls import url

import accounts.views

urlpatterns = [
  url(r'profile/?$', accounts.views.user_profile_page,
      name='user_profile_page'),

配置文件视图(这永远不会被触发AFICT - 在没有帮助的地方插入一个断点):

@login_required
def user_profile_page(request):
    """Returns user home page, with respective user status of surveys."""

    print "User profile accessed: %s" % request

    // user specific data here

    context = {'some': some, 'data': data,
               'here': here, }
    return render(request, 'accounts/profile.html', context)

同样有趣:resolve_url似乎没有像我期望的那样进行重新映射:

(Pdb) resolve_url('/profile')
'/profile'

那不应该指向acccounts/profile127.0.0.1:8000/profile或类似的东西吗?

这是AUTHENTICATION_BACKEND&#39;认证&#39;正在执行的方法(不确定这与标准Django有何不同)。这里的所有答案都暗示authenticate需要接受request参数 - 我可以更新此方法以在此处附加内容吗?:

def authenticate(self, username=None, password=None, **kwargs):
    UserModel = get_user_model()
    if username is None:
        username = kwargs.get(UserModel.USERNAME_FIELD)
    try:
      if username is not None:
        username = username.lower()

      user = UserModel._default_manager.get_by_natural_key(username)
      if user.check_password(password):
        return user
    except UserModel.DoesNotExist:
        # Run the default password hasher once to reduce the timing
        # difference between an existing and a non-existing user (#20760).
        UserModel().set_password(password)

6 个答案:

答案 0 :(得分:7)

Changed in Django 1.10:
In older versions, when you’re manually logging a user in, you must successfully authenticate the user with authenticate() before you call login(). Now you can set the backend using the new backend argument.

如果您使用Django&lt; = 1.10,则必须在登录前使用authenticate方法。否则,您必须至少在login方法中提供身份验证后端。 以下是django docs的代码片段。

username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
    login(request, user)
    # Redirect to a success page.
    ...
else:
    # Return an 'invalid login' error message.
    ...

答案 1 :(得分:3)

试试这个

from django.shorcuts import redirect
from django.contrib.auth import authenticate
def login_page(request):
  profile_page = HttpResponseRedirect('profile')
  if request.user.is_authenticated():
    return profile_page
  form = LoginForm(request.POST or None)
  if request.POST and form.is_valid():
    user = authenticate(request,username=form.cleaned_data['username'],password=form.cleaned_data['password'])

    if user:
      login(request, user)
      return redirect('profile')

答案 2 :(得分:2)

尝试修改:

  profile_page = HttpResponseRedirect('profile')

为:

  profile_page = HttpResponseRedirect(reverse('profile'))

答案 3 :(得分:1)

尝试使用类别基础视图

class Login(FormView, View):

    template_name = 'login/login.html'
    form_class = AuthenticationForm
    success_url = reverse_lazy("your_succes:url")

    def dispatch(self, request, *args, **kwargs):

        if request.user.is_authenticated():
            return HttpResponseRedirect(self.get_success_url())
        else:
            return super(Login, self).dispatch(request, *args, **kwargs)

    def form_valid(self, form):
        login(self.request, form.get_user())
        return super(Login, self).form_valid(form)

答案 4 :(得分:1)

将您的网页重定向到您实际需要使用 Django快捷方式 中的导入重定向的其他网址,并将其用于重定向到必需的URL这是可用的(因为你已经创建了一个Django网站)在 urls.py 你可以看一下youtube视频链接

https://www.youtube.com/watch?v=aCotgGyS2gc&list=PL6gx4Cwl9DGBlmzzFcLgDhKTTfNLfX1IK&index=35

您可能想要尝试的另一件事是使用模板,因为它使Web开发人员的生活更轻松,更安全

回答 关于gunicorn / nginx的问题 ,应用服务器有默认的路由集,你可能已经在生产版中完成了它,添加会话信息时到配置文件页面。

另外,请检查并命名个人资料 目前没有任何文件扩展名

您也可以尝试使用 网址反向

答案 5 :(得分:0)

使用HttpResponseRedirect来触发HTTP 307,而不是触发HTTP 302的HttpResponseTemporaryRedirect

302会发生什么事情,确保重播POST请求。原因如下:

  

RFC 1945和RFC 2068指定不允许更改客户端   重定向请求的方法。但是,大多数现有用户   代理实现将302视为303响应,   无论是什么,都在位置字段值上执行GET   原始请求方法。已添加状态代码303和307   对于希望明确清楚哪种服务器的服务器   期待客户的反应。

     

What's the difference between a 302 and a 307 redirect?