问题 登录表单后的HttpResponseRedirect未重定向到配置文件


我正在尝试获取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/profile 要么 127.0.0.1:8000/profile 或类似的东西?

这是AUTHENTICATION_BACKEND的'authenticate'方法正在执行(不确定这与标准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)

8878
2017-07-08 03:31


起源

你能告诉我们的吗? profile 视图?也许有些东西可疑。因为,在登录后,执行成功的重定向。但是,在配置文件页面中,根据您的调试输出进行了额外的重定向。非常感谢分享你的 profile 另外,为了进一步调查此事。 - zaidfazil
如果您可以发布表单和配置文件视图代码,那么这对我们解决您的问题很有帮助。 - Aniket Pawar
你有没有 启用会话 ?你使用相同版本的Django吗?有什么区别 settings.py ?也正如已经建议的那样,代码为 LoginForm  和 profile 观点可以帮助。 - Michael Rigoni
Django版本的生产和本地版本相同吗? - Muhammad Fahad Manzoor
LoginForm 没有什么令人兴奋的,我补充说 profile 查看它虽然没有任何有趣的东西。 Django是 1.9.1 在测试和prod实例上。 - javanix


答案:


在Django 1.10中更改:
在旧版本中,当您手动登录用户时,必须在调用login()之前使用authenticate()成功验证用户身份。现在,您可以使用新的后端参数设置后端。

如果您使用Django <= 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.
    ...

7
2017-07-13 01:41



我将指定的登录代码更新为auth first - 仍然具有相同的行为。我不明白在哪里 GET /profile 302来自。 - javanix
你能提供你编辑过的代码吗? - Erdenezul
我看到你覆盖身份验证后端的上一次编辑。如果它与原始方法没有区别,为什么要覆盖它?在django代码中,单独的类中有两个authenticate方法,这可能是生产和开发之间运行不同的原因。 - Erdenezul
生产一个使用django的身份验证和开发使用您的自定义身份验证。我根据你的所有代码给出了思考。 - Erdenezul


尝试这个

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

3
2017-07-08 03:41



相同的行为 - 任何想法302被抛出的想法 profile 页? - javanix
尝试编辑ans一次,否则请发布loginform代码 - Exprator


尝试修改:

  profile_page = HttpResponseRedirect('profile')

至:

  profile_page = HttpResponseRedirect(reverse('profile'))

2
2017-07-12 10:30





尝试使用类基础视图

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)

1
2017-07-13 06:34





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

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

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

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

另外,检查 与页面的命名 轮廓 它 目前没有任何文件扩展名

你也可以试试 网址反向


1
2017-07-14 11:33





代替 HttpResponseRedirect 触发HTTP 302,使用a HttpResponseTemporaryRedirect 触发HTTP 307。

会发生什么是302不能确保重播POST请求。原因如下:

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

302和307重定向有什么区别?


0
2017-07-18 22:36