Blame view
decrators.py
3.95 KB
c323519dd 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 |