day 01
models文件
class UserInfo(models.Model): name=models.CharField(max_length=32,verbose_name=‘用户名‘) pwd=models.CharField(max_length=32,verbose_name=‘密码‘) email=models.CharField(max_length=32,verbose_name=‘邮箱‘) roles=models.ManyToManyField(to=‘Role‘) def __str__(self): return self.name class Role(models.Model): name=models.CharField(max_length=32,verbose_name=‘角色名‘) permissions=models.ManyToManyField(to=‘Permission‘) def __str__(self): return self.name class Permission(models.Model): name=models.CharField(max_length=32,verbose_name=‘权限名‘) url=models.CharField(max_length=200,verbose_name=‘网址‘,default=None) # name=models.CharField(max_length=32) def __str__(self): return self.name
用户 --->角色---->权限,正向查询比价方便。所以,多对多的关系,如上图所示。
views文件
Func1:
用户登录后,后台视图函数通过request.POST.get方法 拿到前端传来的数据,对数据库内的数据进行过滤。
在此之前,把models里的所有模型导入到views文件中。
from rbac.models import * def login(request): if request.method==‘POST‘: username=request.POST.get(‘username‘) password=request.POST.get(‘password‘) user=UserInfo.objects.filter(name=username,pwd=password).first()
Func2:
如果验证通过,查询此人的权限。UserInfo -->Role --> Permissions
补充:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
返回一个ValuesQuerySet —— QuerySet 的一个子类,迭代时返回字典而不是模型实例对象。
每个字典表示一个对象,键对应于模型对象的属性名称
if user: permission_list1=user.roles.all() for i in permission_list1: print(i,type(i)) permission_list4 = user.roles.all().values() for i in permission_list4: print(i, type(i)) permission_list2 = user.roles.all().values(‘name‘) for i in permission_list2: print(i,type(i)) permission_list3=user.roles.all().values(‘name‘,‘permissions__name‘,‘permissions__url‘) print(permission_list1,type(permission_list1)) print(permission_list2,type(permission_list2)) print(permission_list3,type(permission_list3)) print(permission_list4,type(permission_list4))
输出:
材料员 <class ‘rbac.models.Role‘> {‘id‘: 4, ‘name‘: ‘材料员‘} <class ‘dict‘> {‘name‘: ‘材料员‘} <class ‘dict‘> <QuerySet [<Role: 材料员>]> <class ‘django.db.models.query.QuerySet‘> <QuerySet [{‘name‘: ‘材料员‘}]> <class ‘django.db.models.query.QuerySet‘> <QuerySet [{‘name‘: ‘材料员‘, ‘permissions__name‘: ‘查询订单‘, ‘permissions__url‘: ‘/order/select/‘}, {‘name‘: ‘材料员‘, ‘permissions__name‘: ‘查询用户‘, ‘permissions__url‘: ‘/user/select/‘}]> <class ‘django.db.models.query.QuerySet‘> <QuerySet [{‘id‘: 4, ‘name‘: ‘材料员‘}]> <class ‘django.db.models.query.QuerySet‘> {‘name‘: ‘材料员‘, ‘permissions__name‘: ‘查询订单‘, ‘permissions__url‘: ‘/order/select/‘} {‘name‘: ‘材料员‘, ‘permissions__name‘: ‘查询用户‘, ‘permissions__url‘: ‘/user/select/‘}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Django 提供一种强大而又直观的方式来“处理”查询中的关联关系,它在后台自动帮你处理JOIN。 若要跨越关联关系,只需使用关联的模型字段的名称,并使用双下划线分隔,直至你想要的字段.
from rbac.models import * def login(request): if request.method==‘POST‘: username=request.POST.get(‘username‘) password=request.POST.get(‘password‘) user=UserInfo.objects.filter(name=username,pwd=password).first() # print(user,type(user)) if user: permission_list=user.roles.all().values(‘name‘,‘permissions__name‘,‘permissions__url‘) for item in permission_list: print(item) return HttpResponse(‘登录成功!‘) return render(request,‘login.html‘)
输出:
{‘name‘: ‘材料员‘, ‘permissions__name‘: ‘查询订单‘, ‘permissions__url‘: ‘/order/select/‘} {‘name‘: ‘材料员‘, ‘permissions__name‘: ‘查询用户‘, ‘permissions__url‘: ‘/user/select/‘}
改进:
可能一个人都多个角色,角色拥有的权限可能有交集。基于这一点考虑,对以上代码进行修正。去掉values()内的name字段。因为这个name字段是roles对象的name,在这里并没有用处,我们需要的是 权限名。
from rbac.models import * def login(request): if request.method==‘POST‘: username=request.POST.get(‘username‘) password=request.POST.get(‘password‘) user=UserInfo.objects.filter(name=username,pwd=password).first() # print(user,type(user)) if user: permission_list=user.roles.all().values(‘permissions__name‘,‘permissions__url‘).distinct() for item in permission_list: print(item) return HttpResponse(‘登录成功!‘) return render(request,‘login.html‘)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------