Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 1.11中间件如何正确重定向_Django_Django Middleware - Fatal编程技术网

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