前言
最近在复习django时发现了装饰器的相关内容,觉得挺有意思的,为此做下记录。
一、装饰器语法
先说明一下装饰器,python的装饰器类似于java的注解,可以用在方法上面。按我的理解,被装饰器装饰的方法,其实是先执行装饰器里面的代码,然后再执行方法里面的代码。语法如下:
def 装饰器名字(传入方法名):
def 执行函数名(传入方法的参数列表):
........
return 传入方法名(传入方法的参数列表)
return 执行函数
二、装饰器解释
下面举个例子,decorator_count是我自定义的一个装饰器
def decorator_count(func):
def dec_count(i, j):
print("装饰器代码已执行")
return func(i, j)
return dec_count
@decorator_count
def count(i, j):
print(i+j)
if __name__ == '__main__':
count(1, 2)
以上程序的执行结果是:
装饰器代码已执行
3
为什么结果是这样,其实count()方法给装饰器装饰之后,装饰器里面的代码和下面代码类似:
def decorator_count(count):
def dec_count(i, j):
print("装饰器代码已执行")
return count(i, j)
return dec_count
这就不难看出,装饰器返回了dec_count()方法,而在dec_count()方法里面,又先执行了print,再执行count(i, j),所以才会有上面的输出顺序。
三、装饰器实现访问和权限控制
页面的访问是先判断用户是否登录,在返回页面,和上面的先执行print(),再执行count(i, j)是不是很像,那使用装饰器判断用户是否登录就很简单了
1、准备
先准备好有关的模型类,视图和页面,以你的实际项目为准,这里只给出有关的视图方法 自定义装饰器“decorator_logined.py”,判断用户是否已经登录
from django.shortcuts import redirect
def already_login(func):
def alr_login(request, *args, **kwargs):
un = request.session.get("username")
if un:
return func(request, *args, **kwargs)
else:
return redirect('/before_index/')
return alr_login
自定义装饰器“decorator_permission.py”,判断用户是否有权限操作
from django.http import HttpResponse
def validate_permission(func):
def valid_per(request, *args, **kwargs):
group_id = request.session.get('group_id')
if group_id == 0:
return func(request, *args, **kwargs)
else:
return HttpResponse("你无权访问!")
return valid_per
在视图中使用()装饰器用在首页和用户列表:
from django.shortcuts import render, redirect
from .forms import UserForm
from .models import User
from Decorator.decorator_permission import validate_permission
from Decorator.decorator_logined import already_login
def login(request):
if request.method == "GET":
return render(request, "login/login.html")
if request.method == "POST":
obj = UserForm(request.POST)
if obj.is_valid():
user = User.objects.values("id", "username", "group_id").filter(**obj.cleaned_data).first()
if user:
request.session['id'] = user['id']
request.session['username'] = user["username"]
request.session['group_id'] = user["group_id"]
return redirect('/index/')
else:
errmsg = {'errmsg': "用户名或者密码错误"}
return render(request, 'login/login.html', errmsg)
content = {"obj": obj}
return render(request, 'login/login.html', content)
@already_login
def index(request):
username = request.session.get("username")
group_id = request.session.get("group_id")
content = {"username": username, "group_id": group_id}
return render(request, 'login/index.html', content)
@already_login
@validate_permission
def userList(request):
userList = User.objects.all()
content = {"userList": userList}
return render(request, "user/user_list.html", content)
def before_index(request):
return render(request, "login/before_index.html")
注意:使用多个装饰器装饰同一个方法时装饰器是由上往下依次执行
2、测试
我的用户列表如下,只有group_id为0的用户能访问用户列表:  没登录时输入首页地址:   登录之后输入用户列表地址:    登录管理员账号输入用户列表地址:    大功告成!!!想要判断用户是否登录和用户操作权限,只需要引入对应的装饰器就可以啦。 有什么问题欢迎在评论区留言。
|