好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Django装饰器login_required改进

Django认证中间件需要对所有请求做过滤,但有些时候需要在个别视图函数或者视图类的方法上做认证。

对视图函数的认证装饰器很容易写,但是对于视图类的方法使用装饰器,需要解决self的问题。可以在装饰器中调整第一个参数,但是这个方法太过笨拙,今日突发奇想,对于cbv方法,如果能在as_view时增加排除认证,这样也不失为一种好的办法。

理解下面装饰器,需要理解cbv中as_view函数本质,就是把对view实例的调用转换视图函数的调用,在内部再根据方法dispath。

装饰器实现如下

 def login_required(exclude_methods): # 列表指定排除认证的方法['post']
    def _login_required(viewfunc):
        # 参照django.contrib.auth.decorators.login_required
        @wraps(viewfunc)
        def wrapper(request, *args, **kwargs):
            method = request.method.lower()
            if method in exclude_methods:
                return viewfunc(request, *args, **kwargs)
            else:
                if request.user.is_authenticated:
                    print('认证了')
                    return viewfunc(request, *args, **kwargs)
                print('未认证通过')
                return HttpResponse(status=401)
        return wrapper
    if callable(exclude_methods): # 兼容之前调用,如果是无参调用就是函数,帮它往里面调用一层返回
        fn = exclude_methods
        exclude_methods = () # 表示没什么方法method要排除,都要认证
        return _login_required(fn) # 主要这个fn
    return _login_required 

到cbv的路由配置,如下

 from django.urls import path
from .views import PostView
from user.views import login_required

urlpatterns = [
    path('', login_required(['get'])(PostView.as_view())), # 排除get方法,get方法不认证
] 

普通视图函数认证使用如下

 @login_required
def getpost(request:HttpRequest):  
    return JsonResponse({}) 

希望这个实现,能够抛砖引玉,帮助大家

查看更多关于Django装饰器login_required改进的详细内容...

  阅读:23次