Django 1.11中间件如何正确重定向
我在使用中间件时遇到了无法解决的困难。如果用户没有设置公司,我正在处理的项目应该将所有访问网站任何部分的请求重定向到添加公司页面。为此,我正在编写一个自定义中间件。但是,以下代码不起作用:Django 1.11中间件如何正确重定向,django,django-middleware,Django,Django Middleware,我在使用中间件时遇到了无法解决的困难。如果用户没有设置公司,我正在处理的项目应该将所有访问网站任何部分的请求重定向到添加公司页面。为此,我正在编写一个自定义中间件。但是,以下代码不起作用: class ProjectTrackingMiddleWare(MiddlewareMixin): ''' Note that this Middleware should come after all other middlewares in order to
class ProjectTrackingMiddleWare(MiddlewareMixin):
'''
Note that this Middleware should come after all other middlewares
in order to
'''
def __init__(self, get_response=None):
''' One-time configuration called when the web-server starts '''
self.get_response = get_response
def __call__(self, request):
''' To be executed on every request. '''
the_request = self.process_request(request)
response = self.get_response(request)
return response
def process_request(self, request):
the_user = request.user
print ('the_user: ', the_user)
## CASE 1: User is not authenticated --> Redirect to login page
if the_user.
return HttpResponseRedirect(reverse('accounts:login')) # <-- This part works
the_company = the_user.userprofile.employer
if the_user and not the_company:
print ('the company: ', the_company)
return HttpResponseRedirect(reverse('project_profile:add_company')) #<-- Does NOT redirect correctly
if the_user.projects.all().count() > 1:
request.project = the_user.projects.all().order_by('-date_modified')[0]
return request
当我尝试访问/development/
页面时,似乎发生了重定向,因为url=“/project/add/”>
表明它确实在HttpResponseRedirect上拾取了
因此,以下是我的问题:
1) 似乎可以在进程中重定向请求,还是不建议这样做?如果没有,那么我应该在哪里检查这些全局变量并将用户重定向到正确的设置
2) 如何获得与客户端类似的重定向链:
client.get(reverse(‘dashboard’), follow = True)
编辑1:
正如Iain在评论中所建议的,我应该将_请求传递给get_响应方法。然而,这并没有解决这个问题。Django现在抱怨HttpResponseRedirect没有属性路径:
“HttpResponseRedirect”对象没有属性“path”
奇怪的是,如果我根据公司的存在将其重定向到登录url,我也会收到此错误,但如果我将匿名用户重定向到登录url,我不会收到此错误:
## Redirects successfully when the user is anonymous. If the user is logged-in already, it skips it as expected
if the_user.is_anonymous():
return HttpResponseRedirect(reverse('accounts:login'))
### Throws attribute excpetion: 'HttpResponseRedirect' object has no attribute 'path'
if not the_company:
return HttpResponseRedirect(reverse('accounts:login'))
因此,错误似乎与请求对象有关。但是,我现在还不明白。有什么想法吗?您编写中间件的方式不太合理。您的
process\u request
方法返回一个Response
对象,然后将其传递给get\u Response
。这是无效的-get\u response
接受请求,而不是响应
由于您想在某些情况下使响应短路,因此如果要重定向,需要完全跳过调用get\u response
。这意味着您需要在调用get\u response
之前进行检查。大概是这样的:
def __call__(self, request):
# Perform your checks here, and redirect if necessary
the_user = request.user
## CASE 1: User is not authenticated --> Redirect to login page
if not the_user:
return HttpResponseRedirect(reverse('accounts:login'))
the_company = the_user.userprofile.employer
if not the_company:
return HttpResponseRedirect(reverse('project_profile:add_company'))
if the_user.projects.all().count() > 1:
request.project = the_user.projects.all().order_by('-date_modified')[0]
# Now that you've done your checks, let the rest of the request process run
response = self.get_response(request)
return response
(由于不再使用,
process\u-request
方法,请将其删除)。我最终解决这个问题的方法是使用process\u-view-hook
AUTHENTICATION_EXEMPT_URLS = (
reverse('accounts:signup').lstrip('/'), # reverse part returns '/accounts/login' and lstrip('/') drops the '/': 'accounts/login'
reverse('accounts:login').lstrip('/'),
reverse('accounts:logout').lstrip('/'),
)
COMPANY_EXEMPT_URLS = ( reverse('project_profile:add_company').lstrip('/'),
reverse('accounts:signup').lstrip('/'),
reverse('accounts:login').lstrip('/'),
reverse('accounts:logout').lstrip('/'),
)
class MyRedirectMiddleware(MiddlewareMixin):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
def process_view(self, request, view_func, view_args, view_kwargs):
assert hasattr(request, 'user') # being logged in is required
path = request.path_info.lstrip('/')
if not request.user.is_authenticated():
if not any(url for url in AUTHENTICATION_EXEMPT_URLS if url==path):
# if the url is not in any of the list's urls, redirect to authentication page
return redirect(settings.LOGIN_URL)
# Note that userprofile is created using a signal currently at user_profile/models.py
the_company = request.user.userprofile.employer
if request.user.is_authenticated() and not the_company:
# user should setup a copmany first:
if not any( url for url in COMPANY_EXEMPT_URLS if url==path):
return redirect(reverse('project_profile:add_company'))
我要感谢所有花时间帮助我的人,你们太棒了。
response=self.get\u response(请求)
应该传递请求
而不是这里的请求
?@IainShelvington给我一个不同的错误AttributeError:“HttpResponseDirect”对象没有属性“path”
和请求:
AUTHENTICATION_EXEMPT_URLS = (
reverse('accounts:signup').lstrip('/'), # reverse part returns '/accounts/login' and lstrip('/') drops the '/': 'accounts/login'
reverse('accounts:login').lstrip('/'),
reverse('accounts:logout').lstrip('/'),
)
COMPANY_EXEMPT_URLS = ( reverse('project_profile:add_company').lstrip('/'),
reverse('accounts:signup').lstrip('/'),
reverse('accounts:login').lstrip('/'),
reverse('accounts:logout').lstrip('/'),
)
class MyRedirectMiddleware(MiddlewareMixin):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
def process_view(self, request, view_func, view_args, view_kwargs):
assert hasattr(request, 'user') # being logged in is required
path = request.path_info.lstrip('/')
if not request.user.is_authenticated():
if not any(url for url in AUTHENTICATION_EXEMPT_URLS if url==path):
# if the url is not in any of the list's urls, redirect to authentication page
return redirect(settings.LOGIN_URL)
# Note that userprofile is created using a signal currently at user_profile/models.py
the_company = request.user.userprofile.employer
if request.user.is_authenticated() and not the_company:
# user should setup a copmany first:
if not any( url for url in COMPANY_EXEMPT_URLS if url==path):
return redirect(reverse('project_profile:add_company'))