权限(1)
一. global_settings.py全局配置文件
- 所在位置:
from django .conf import settings 进入settings
settings = LazySettings() 进入LazySettings
在LazySettings中引用了global_settings
- 平常所设置的settings.py的权重大于global_settings.py,所以在settings.py中配置的内容会覆盖掉global_settings.py中的内容,如果settings.py中没有,默认用global_settings.py中的配置
- 例:session过期时间的设置
Session的默认过期时间为14天:SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2
设置为10秒钟SESSION_COOKIE_AGE = 10
二. Limit_choice_to语法
class ConsultRecord(models.Model):
customer = models.ForeignKey('Customer',on_delete=models.CASCADE)
note = models.TextField(verbose_name="跟进内容")
consultant=models.ForeignKey("UserInfo",on_delete=models.CASCADE,limit_choices_to={"pk",3})
正常情况下modelform在渲染前端页面时,有ForeignKey的字段默认会渲染关联表中的所有选项,但是在实际生产中,有时不会需要显示所有选项,如在crm中,添加跟进记录时,不需要让销售从所有的销售中选择一个人,只需固定显示当前登录的销售即可,此处的limit_choices_to相当于UserInfo.objects.filter(pk=3)
三.权限组件
Web网站的访问限制
1.方案
(1).简单方案:
用户表
1 Id name 2 3 1 a1 4 5 2 a2
权限表
1 Id use url title 2 3 1 a /index/ 主页 4 5 2 a /customer/ 查看客户 6 7 3 a /customer_add/ 添加 8 9 4 b /index/ 主页
此方案的弊端:每次创建用户都要添加多条数据,浪费时间和空间
(2).方案二(RBAC:role based access control)基于角色的访问控制权限
用户表
1 Id name 2 3 1 a1 4 5 2 a2
多对多user2role表
Id user_id role_id
1 1 3
1 2 3
角色表
Id title 1 ceo 2 销售
多对多role2permission
Id role_id permission
1 3 1
1 3 2
1 3 3
1 3 4
权限表permission
Id use url title 1 a /index/ 主页 2 a /customer/ 查看客户 3 a /customer_add/ 添加 4 b /index/ 主页
2.admin的使用补充
想让每一个实例显示的内容更丰富一些
(1) 改变模型类的__str__方法的内容
def __str__(self):
return self.title
(2)在admin.py中添加对用的约束显示内容的类
1 class PermissionConfig(admin.ModelAdmin): 2 list_display=["pk","title","url"] #显示哪几列 3 ordering = ["pk"] #按照哪种规则排序 4 admin.site.register(Permission,PermissionConfig)
替代admin.site.register(Permission)
四.一套可插拔式的权限组件
1.为项目创建权限所需要的三张表:用户表,角色表,权限表
在models.py中:
1 from django.db import models 2 3 class User(models.Model): 4 name=models.CharField(max_length=32) 5 pwd=models.CharField(max_length=32) 6 roles=models.ManyToManyField(to="Role") 7 def __str__(self): 8 return self.name 9 10 class Role(models.Model): 11 title=models.CharField(max_length=32) 12 permissions=models.ManyToManyField(to="Permission") 13 def __str__(self): 14 return self.title 15 16 class Permission(models.Model): 17 title=models.CharField(max_length=32) 18 url=models.CharField(max_length=32) 19 def __str__(self): 20 return self.title
2.创建相应的路径
1 def customer(request): 2 return HttpResponse("this is customer.") 3 4 def addcustomer(request,id): 5 return HttpResponse("this is addcustomer.") 6 7 def editcustomer(request,id): 8 return HttpResponse("this is editcustomer.") 9 10 def delecustomer(request,id): 11 return HttpResponse("this is customer.") 12 13 def product(request): 14 return HttpResponse("this is product.") 15 16 def addproduct(request,id): 17 return HttpResponse("this is addproduct.") 18 19 def editproduct(request,id): 20 return HttpResponse("this is editproduct.") 21 22 def deleproduct(request,id): 23 return HttpResponse("this is deleproduct.")
3.为相应的路径相应的角色分配权限
如果利用admin组件添加,在admin.py中:
1 from django.contrib import admin 2 3 from app01.models import * 4 admin.site.register(User) 5 admin.site.register(Role) 6 class PermissionConfig(admin.ModelAdmin): 7 list_display=["pk","title","url"] #显示哪几列 8 ordering = ["-pk"] #按照哪种规则排序 9 10 admin.site.register(Permission,PermissionConfig)
4.登录时验证
1 def login(request): 2 if request.method=="GET": 3 return render(request,"login.html") 4 else: 5 user=request.POST.get("user") 6 pwd=request.POST.get("pwd") 7 use=User.objects.filter(name=user,pwd=pwd).first() 8 if use: 9 request.session["user_id"]=use.pk 10 11 #注入session用来判断是否登录 12 permissions__url=Role.objects.filter(user__name=user).values("permissions__url") 13 #判断登录人的角色,根据角色查找权限 14 permissions__url_list=[] 15 for item in permissions__url: 16 print(item["permissions__url"]) 17 permissions__url_list.append(item["permissions__url"]) 18 request.session["permission"]=permissions__url_list 19 20 #把权限放到列表中,注入session中 21 return HttpResponse("登录成功") 22 else: 23 return HttpResponse("用户名或密码错误")
5.登录各个地址时,都要校验该路径是否在session列表,直接在中间件中判断
在自定义的中间件中:
1 import re 2 from django.utils.deprecation import MiddlewareMixin 3 from django.shortcuts import HttpResponse,redirect 4 class SessionMiddleware(MiddlewareMixin): 5 def process_request(self, request): 6 path=request.path 7 permission=request.session.get("permission") 8 # 白名单 9 for reg in ["/login/","/admin/*"]: 10 11 #以admin开头的路径问题 12 ret=re.search(reg,path) 13 if ret: 14 return None 15 # 判断是否登录 16 user_id=request.session.get("user_id") 17 if not user_id: 18 return redirect("/login/") 19 # 校验权限 20 for reg in permission: 21 reg="^%s$" % reg 22 ret=re.search(reg,path) 23 if ret: 24 return None 25 return HttpResponse("无权访问")
不要忘了将中间件的路径告诉配置文件
1 MIDDLEWARE = [ 2 'django.middleware.security.SecurityMiddleware', 3 'django.contrib.sessions.middleware.SessionMiddleware', 4 'django.middleware.common.CommonMiddleware', 5 'django.middleware.csrf.CsrfViewMiddleware', 6 'django.contrib.auth.middleware.AuthenticationMiddleware', 7 'django.contrib.messages.middleware.MessageMiddleware', 8 'django.middleware.clickjacking.XFrameOptionsMiddleware', 9 "app01.permission_middleware.SessionMiddleware", 10 ]