Blame view

decrators.py 3.95 KB
c323519dd   zhenchaozhu   m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  # coding: utf-8
  
  import django.http
  from functools import wraps
  from django.conf import settings
  from django.utils.decorators import available_attrs
  from django.shortcuts import resolve_url
  from django.utils.six.moves.urllib.parse import urlparse
  
  def weapp_django_logout(request, response):
      assert isinstance(request, django.http.HttpRequest)
      assert isinstance(response, django.http.HttpResponse)
      # 请求统一认证登出
      response.delete_cookie('pt')
      response.delete_cookie('pu')
      response.delete_cookie('username')
      return response
  
  def weapp_logout(func=weapp_django_logout):
      """
      Django登出视图函数装饰器
      :param func: 处理登出逻辑的函数,接受request和response两个参数
      :return:
      """
      return auth_decorator_factory(func)
  
  
  def auth_decorator_factory(func=None):
      """
      登录登出装饰器工厂函数,允许用户自定义外部登录登出函数
      :param func:
      :return:
      """
  
      def decorator(view_func):
          @wraps(view_func)
          def _wrapped_view(request, *args, **kwargs):
              response = view_func(request, *args, **kwargs)
              if func:
                  func(request, response)
              return response
  
          return _wrapped_view
  
      return decorator
  
  import json
  
  from django.http import JsonResponse
  
  
  class QCCRJsonResponse(JsonResponse):
      """
      封装了返回码和信息的JsonResponse类
      """
      def __init__(self, obj=None, code=200, msg="success", status=200, **kwargs):
          data = {"code": code, "msg": msg, "result": json.loads(obj) if isinstance(obj, (str, unicode)) else obj}
          super(QCCRJsonResponse, self).__init__(data=data, status=status, **kwargs)
  
  
  class QCCRErrorResponse(QCCRJsonResponse):
      """
      请求错误
      """
      def __init__(self, obj=None, code=400, msg="failure", status=400, **kwargs):
          super(QCCRErrorResponse, self).__init__(obj=obj, code=code, msg=msg, status=status, **kwargs)
  
  def user_passes_test(test_func, login_url=None,
                       redirect_field_name=getattr(settings, "QCCR_REDIRECT_FIELD_NAME", 'redirect')):
      """
      本装饰器通过test_func函数,检查views是否通过相应的检测,未通过则跳转到登录页面;test_func函数接受user对象作为参数,通过则返回True
      """
  
      def decorator(view_func):
          @wraps(view_func, assigned=available_attrs(view_func))
          def _wrapped_view(request, *args, **kwargs):
              if test_func(request.user):
                  return view_func(request, *args, **kwargs)
              # 如果未通过检查,且为ajax请求,返回403
              if request.is_ajax():
                  return QCCRErrorResponse(code=403, msg="用户身份检查失败", status=403)
              # 非ajax请求,跳转到登录页面
              path = request.build_absolute_uri()
              resolved_login_url = resolve_url(login_url or getattr(settings, "QCCR_LOGIN_URL", '/login/'))
              login_scheme, login_netloc = urlparse(resolved_login_url)[:2]
              current_scheme, current_netloc = urlparse(path)[:2]
              if ((not login_scheme or login_scheme == current_scheme) and
                      (not login_netloc or login_netloc == current_netloc)):
                  path = request.get_full_path()
              from django.contrib.auth.views import redirect_to_login
              return redirect_to_login(path, resolved_login_url, redirect_field_name)
  
          return _wrapped_view
  
      return decorator
  
  
  def weapp_login_required(function=None,
                          redirect_field_name=getattr(settings, "QCCR_REDIRECT_FIELD_NAME", 'redirect'),
                          login_url=None):
      """
      登录状态检查装饰器,如果未登录,则直接跳转到登录页面
      """
      actual_decorator = user_passes_test(
          lambda u: u.is_authenticated(),
          login_url=login_url,
          redirect_field_name=redirect_field_name
      )
      if function:
          return actual_decorator(function)
      return actual_decorator