在登录表单后,HttpResponseRedirect不会重定向到概要文件。

时间:2022-10-20 10:27:42

I'm trying to get a local copy of a Django site working. The production site works just fine on login, but my local instance doesn't redirect to the profile page after completing the login form.

我正在尝试获得Django站点的本地副本。生产站点在登录时运行良好,但是我的本地实例在完成登录表单后不会重定向到配置文件页面。

This is the login_page view:

这是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})

This is what the debug output of the server shows:

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

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

After the above, the browser is left at http://127.0.0.1:8000/login?next=/profile and just displays the standard login page.

在上面,浏览器在http://127.0.0.1:8000/登录?next=/profile并只显示标准登录页面。

Again, identical code is working on the same version of Django in production (though running through gunicorn/nginx instead of django-admin runserver), so it makes me think that there's something in my Django config that I'm missing rather than an actual code problem.

同样,相同的代码在产品中使用相同版本的Django(虽然是通过gunicorn/nginx而不是通过Django -admin runserver运行),所以我认为我在Django配置中漏掉了一些东西,而不是实际的代码问题。

urls.py entries:

url。py条目:

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

accounts/urls.py:

账户/ urls . py:

from django.conf.urls import url

import accounts.views

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

Profile view (this never gets triggered AFICT - sticking a breakpoint in there doesn't help):

配置文件视图(这不会触发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)

Also interesting: resolve_url doesn't seem to do the remapping like I would expect:

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

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

Shouldn't that point to acccounts/profile or 127.0.0.1:8000/profile or something like that?

那不应该指向acccounts/profile,或者127.0.1:0:8000/profile之类的东西吗?

This is the AUTHENTICATION_BACKEND's 'authenticate' method that is getting executed (not sure how this differs from standard Django). All of the answers here imply that authenticate needs to accept the request argument - can I update this method to append something here?:

这是正在执行的authentication_后台的“身份验证”方法(不确定这与标准的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 个解决方案

#1


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.

If you using Django<=1.10, you must use authenticate method before you login. Otherwise, you have to feed authentication backend at least in login method. Here is the code snippet from django docs.

如果使用Django<=1.10,则必须在登录之前使用authenticate方法。否则,您必须至少在登录方法中提供后端身份验证。下面是django文档的代码片段。

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.
    ...

#2


3  

try this

试试这个

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


2  

Try modifying:

试着修改:

  profile_page = HttpResponseRedirect('profile')

to:

:

  profile_page = HttpResponseRedirect(reverse('profile'))

#4


1  

try with class bassed views

尝试使用类基视图

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)

#5


1  

to get your page redirected to some other URL you actually require to use import redirect from Django shortcuts and utilize this to redirect to the required URL this is the ones available(as you already have created a Django website) in urls.py you can Have a look at the youtube video link

要将页面重定向到其他URL,您实际上需要使用从Django快捷方式导入重定向,并利用此重定向到所需的URL,这是URL中可用的URL(正如您已经创建了Django网站)。你可以看看youtube上的视频链接

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

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

Another thing You may want to try is using templates as it makes Web developer's life Easier and safer

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

Answering the Question about gunicorn/nginx the application server has its default route set, you might have done it in the production build, to the profile page when the session info is added.

在回答关于gunicorn/nginx的问题时,应用服务器有其默认的路由集,您可能已经在产品构建中这样做了,当会话信息被添加到概要文件页面时。

Also, check with the naming of the page profile it presently does not have any file extensions

另外,请检查当前没有任何文件扩展名的页面配置文件的命名。

you can also try with URL reverse

您还可以尝试反向URL

#6


0  

Instead of HttpResponseRedirect which triggers a HTTP 302, use a HttpResponseTemporaryRedirect to trigger a HTTP 307.

与触发HTTP 302的HttpResponseRedirect不同,使用HttpResponseTemporaryRedirect来触发HTTP 307。

What happens is that 302 does not ensure the replay of the POST request. The reason is as follows:

发生的情况是302不能确保POST请求的重播。原因如下:

RFC 1945 and RFC 2068 specify that the client is not allowed to change the method on the redirected request. However, most existing user agent implementations treat 302 as if it were a 303 response, performing a GET on the Location field-value regardless of the original request method. The status codes 303 and 307 have been added for servers that wish to make unambiguously clear which kind of reaction is expected of the client.

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

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

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

#1


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.

If you using Django<=1.10, you must use authenticate method before you login. Otherwise, you have to feed authentication backend at least in login method. Here is the code snippet from django docs.

如果使用Django<=1.10,则必须在登录之前使用authenticate方法。否则,您必须至少在登录方法中提供后端身份验证。下面是django文档的代码片段。

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.
    ...

#2


3  

try this

试试这个

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


2  

Try modifying:

试着修改:

  profile_page = HttpResponseRedirect('profile')

to:

:

  profile_page = HttpResponseRedirect(reverse('profile'))

#4


1  

try with class bassed views

尝试使用类基视图

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)

#5


1  

to get your page redirected to some other URL you actually require to use import redirect from Django shortcuts and utilize this to redirect to the required URL this is the ones available(as you already have created a Django website) in urls.py you can Have a look at the youtube video link

要将页面重定向到其他URL,您实际上需要使用从Django快捷方式导入重定向,并利用此重定向到所需的URL,这是URL中可用的URL(正如您已经创建了Django网站)。你可以看看youtube上的视频链接

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

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

Another thing You may want to try is using templates as it makes Web developer's life Easier and safer

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

Answering the Question about gunicorn/nginx the application server has its default route set, you might have done it in the production build, to the profile page when the session info is added.

在回答关于gunicorn/nginx的问题时,应用服务器有其默认的路由集,您可能已经在产品构建中这样做了,当会话信息被添加到概要文件页面时。

Also, check with the naming of the page profile it presently does not have any file extensions

另外,请检查当前没有任何文件扩展名的页面配置文件的命名。

you can also try with URL reverse

您还可以尝试反向URL

#6


0  

Instead of HttpResponseRedirect which triggers a HTTP 302, use a HttpResponseTemporaryRedirect to trigger a HTTP 307.

与触发HTTP 302的HttpResponseRedirect不同,使用HttpResponseTemporaryRedirect来触发HTTP 307。

What happens is that 302 does not ensure the replay of the POST request. The reason is as follows:

发生的情况是302不能确保POST请求的重播。原因如下:

RFC 1945 and RFC 2068 specify that the client is not allowed to change the method on the redirected request. However, most existing user agent implementations treat 302 as if it were a 303 response, performing a GET on the Location field-value regardless of the original request method. The status codes 303 and 307 have been added for servers that wish to make unambiguously clear which kind of reaction is expected of the client.

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

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

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