代码之家  ›  专栏  ›  技术社区  ›  Muhammad Hassan

如果用户在特定url上,并且未通过测试,则阻止他进入另一个视图

  •  1
  • Muhammad Hassan  · 技术社区  · 9 年前

    我正在一个django项目中工作,在该项目中,如果出现以下情况,我需要阻止用户进入另一个视图

    1. 他正在写一篇论文
    2. 未通过测试

    如果他在特定页面上。若用户在另一个页面上,但他并没有通过测试,他将被允许去任何地方。

    例如,如果我有三个选项卡 Tab1 , Tab2 Tab3 。如果用户打开 选项卡2 并且未通过测试 A ,他不能继续 选项卡1 表3 .但如果他在 选项卡1 表3 但他没有通过考试,他仍然可以去 选项卡2 表3 . 当用户单击 选项卡1 我想看看他是否在 选项卡2 或者不是。如果他没有,他将被允许去。但如果他在 选项卡2 ,我将检查用户是否通过测试。如果他通过了考试,他将被允许去。否则他将不被允许去。

    我试着用 @user_passes_test decorator,但它使用user作为参数,我无法获取当前url。有没有其他的方法来做这个或任何其他的装饰,我可以使用?或者我必须写我自己的定制装饰?

    2 回复  |  直到 9 年前
        1
  •  2
  •   GrvTyagi    9 年前

    你可以通过创建一个中间件来解决这个问题,
    在中间件上,只需通过request.META.get('HTTP_REFERER',None)检查用户的转发url。
    然后检查测试条目,如果数据库中存在用户尝试测试,则传递或返回错误页面或您想要的内容。

    def process_response(self, request, response):
        referer_path = str(request.META.get('HTTP_REFERER',None))
        request_path = str(request.path)        
        match_pattern = r"[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"
    
        if re.search(match_pattern, request_path) and request_path.__contains__('/lms/media/video/articulate/') and response.status_code == 200:
             #what you want logic
    

    有关详细信息,请参阅 https://docs.djangoproject.com/en/1.9/topics/http/middleware/

        2
  •  1
  •   Muhammad Hassan    9 年前

    下面是一个定制的装饰器 request 对象作为输入,我用它检查了当前位置,并检查用户是否通过了特定的测试。

    from django.http import HttpResponseRedirect
    
    
    def request_passes_test(test_func, redirect_url=None, message=None, status=401):
    """
    Decorator for resources that checks that the request passes the given test.
    If the request fails the test a 401 (Unauthorized) response is returned,
    otherwise the view is executed normally. The test should be a callable that
    takes an HttpRequest object and any number of positional and keyword
    arguments as defined by the urlconf entry for the decorated resource.
    """
        def decorator(view_func):
            def _wrapped_view(request, *args, **kwargs):
                if not test_func(request, *args, **kwargs):
                    return HttpResponseRedirect(redirect_url)
                return view_func(request, *args, **kwargs)
            return _wrapped_view
        return decorator
    

    它可以用作

    @request_passes_test(test_function, redirect_url='/url/')