首先在models.py里先加入我们需要的表 Meta里的参数自己定义,我这里定义了3个,作为我的权限分类,定义好之后我们可以在django-admin里看到我们的权限分类,当我们添加用户的时候也可以指定这3个权限给用户。
class Permission(models.Model):
name = models.CharField("权限名称", max_length=64)
url = models.CharField('URL名称', max_length=255)
per_method = models.CharField('请求方法', max_length=10)
describe = models.CharField('描述', max_length=255)
def __str__(self):
return self.name
class Meta:
verbose_name = '权限表'
verbose_name_plural = verbose_name
#权限信息,这里定义的权限的名字,后面是描述信息,描述信息是在django admin中显示权限用的
permissions = (
('readonly', '全平台只读'),
('app_admin','平台管理员权限'),
('dashboard','仪表盘只读'),
定义好我们的权限表,我们再定义个权限判断的方法 在models.py的同级目录下新建一个permission.py,名字随意定
# -*- coding:utf-8 -*-
from django.shortcuts import render
from app.models import *
from django.db.models import Q
from django.urls import resolve #此方法可以将url地址转换成url的name
import logging
from logging.handlers import TimedRotatingFileHandler
logger = logging.getLogger("ALERT LOG FORMAT")
logger.setLevel(logging.DEBUG)
LOG_FILE="/tmp/alert.log"
fh = TimedRotatingFileHandler(LOG_FILE,when='D',interval=1,backupCount=30) #按天分割日志,保留30天
fh.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
fh.setFormatter(formatter)
logger.addHandler(fh)
def perm_check(request, *args, **kwargs):
user_perm = list(request.user.get_all_permissions()) #获取用户权限
if len(user_perm) < 0:
print("用户没有权限")
return False
user_method = request.method #获取用户的方法get|post
# get_perm = Permission.objects.filter(name=user_perm) #使用用户权限名称查找用户的具体权限
url_obj = resolve(request.path_info)
url_name = url_obj.url_name #获取当前用户访问的url地址
for perm in user_perm:
query = Permission.objects.filter(name=perm.split(".")[1])
print(query)
method = query[0].per_method
url = query[0].url
if url == "ALL" and method == "ALL":
print("用户具有平台管理员权限")
return True
elif url == "ALL" and method == "GET":
print("用户具有平台只读权限")
return True
else:
if url_name == url and user_method == method:
print("权限已经匹配")
return True
else:
print("权限没有匹配")
return False
def check_permission(fun): #定义一个装饰器,在views中应用
def wapper(request, *args, **kwargs):
if perm_check(request, *args, **kwargs): #调用上面的权限验证方法
return fun(request, *args, **kwargs)
return render(request, '403.html', locals())
return wapper
这个方法会提取用户的权限和上面我们定义的表中的权限相匹配,成功的返回True,否则返回False 下面是我简单定义的权限
(root[@127.0.0.1](https://my.oschina.net/u/567043):)[app]> select * from app_permission;
+----+-----------+-----------+------------+-----------------------+
| id | name | url | per_method | describe |
+----+-----------+-----------+------------+-----------------------+
| 1 | dashboard | dashboard | GET | 主页浏览权限 |
| 2 | app_admin | ALL | ALL | 平台管理员权限 |
| 4 | readonly | ALL | GET | 全平台只读 |
+----+-----------+-----------+------------+-----------------------+
好了,最后在views里调用
from app.permission import check_permission
@csrf_exempt
@check_permission
def backup_recovery(request):
if request.user == "AnonymousUser":
return HttpResponseRedirect('/login')
data = backup_failure.objects.all()
return render(request,'backup_recovery.html',{'data':data})
简单的使用装饰器的方法调用一下即可。