概念:本质上是一个python闭包函数,可以让其他函数在不需要做任何代码的变动的前提下增加额外的功能;返回值也是函数的对象,
作用:提高代码重复利用率,缩减代码量,同时也有助于代码的可读性和可维护性
应用场景:
1 计算某个函数的运行时间和运行次数(通过在外层函数加上时间计算函数或运算次数统计函数)
2 框架的路由传参()
3 函数的运行日志(插入日志)
4 多个函数实现事务处理的一致性(让函数一起成功运行,或一起运行失败)
5 缓存(实现缓存处理)
6 权限校验(在函数外层套上权限验证的代码,实现权限校验)
在视图入口处,即路由分发的过程中使用
通过as_view(),类会被转换成视图函数。在转换好的视图函数上直接使用装饰器函数
from django.contrib.auth.decorators import login_required, permission_required
from django.views.generic import TemplateView
from .views import VoteView
urlpatterns = [
path('about/', login_required(TemplateView.as_view(template_name="secret.html"))),
path('vote/', permission_required('polls.can_vote')(VoteView.as_view())),
]
此方法会为该类的所有的方法加上装饰器,而不能为单个方法添加
使用 method_decorator 方法将其转换为适用于类视图方法的装饰器
method_decorator方法支持同时添加多个装饰器,先将要用的装饰器放在一个元祖或list中
decorators = [never_cache, login_required]
@method_decorator(decorators, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'
@method_decorator(never_cache, name='dispatch')
@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'
不用指定name值,name值默认为空
from django.contrib.auth.decorators import login_required
from django.views import View
from django.utils.decorators import method_decorator
class Order(View):
@method_decorator(login_required)
def get(self, request):
return render(request, 'order.html')
必须把方法名称作为参数给到name
name属性只支撑一个对象,当需要为多个方法使用同一个装饰器时,需要重复添加
@method_decorator(login_required, name='post')
@method_decorator(login_required, name="get")
class Logout(View):
def get(self, request):
auth.logout(request)
return redirect('/login_c/')
def post(self, request):
return redirect('/cheeck/')
将name设为dispatch,dispatch内部通过反射来实现函数执行
@method_decorator(login_required, name="dispatch")
class Logout(View):
def get(self, request):
auth.logout(request)
return redirect('/login_c/')
def post(self, request):
return redirect('/cheeck/')
在Django 1.9之前,不能对类使用method_decorator,必须重写dispatch方法;
在Django 1.9版本,有内部定义dispatch方法
Django 1.9 前版本
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView
class ProtectedView(TemplateView):
template_name = 'secret.html'
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
Django 1.9及以后版本
@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'
method_decorator方法会对收到的被装饰对象进行判断:
如果是方法,继续进行装饰;如果是类,需要调取name值作为实际被装饰对象。所以在类中使用时,需要把方法名给name
def login(request):
if request.method == "GET":
return render (request, "login.html")
else:
username = request.POST.get('username')
password = request.POST.get('password')
user_obj = auth.authenticate(username=username, password=password)
if user_obj:
auth.login(request, user_obj)
path = request.GET.get('next') or '/index/'
return redirect(path)
return redirect('/login/')
登录验证(通过session key检查是否登录),验证通过后可征程执行请求,验证失败后记录当前请求地址并跳转登录页面,在登录成功后跳转已经记录好下来的请求地址
全局设置中后设置登录验证后跳转地址:
LOGIN_URL = '/accounts/login/'
需要在setting中重新定义:
LOGIN_URL = '/login/'
权限验证(通过数据库中的auth_permission数据表检查),权限能约束用户行为,当业务逻辑中涉及到权限检查时
对页面进行缓存(可在参数中定义过期时间)
控制缓存
私有缓存数据(用户浏览器)和公有缓存数据(提供者),需要一个方法告诉缓存那些数据是私有的,那些是可以共享的
禁用缓存,节省存储空间
Django框架在进行路由分发时,不管是FBV还是CBV,完全依赖于用户请求的URL,不考虑请求所使用的HTTP方法。
也就是说,对同一个URL使用不同的HTTP方法,都将由同一个视图函数处理。
通过这个函数设定只允许的请求方法,从而拦截不允许的请求方法并在拦截后返回405错误,参数为列表形式
基于require_http_methods方法,有三个可直接使用的方法
require_GET() 只支持GET请求
require_POST() 只支持POST请求
require_SAFE() 只支持GET和HEAD请求
局部设置防跨站请求伪造功能(全局用中间件)
标识一个视图可以被跨域访问,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件
为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件