權限組件 1 項目與應用 2 什麼是權限? 一個包含正則表達式url就是一個權限 who what how ---------->True or Flase UserInfor name pwd permission=models.manytomany(Permission) name pwd egon 123 alex 456 A 111 B 222 C 333 D 444 Permission url=..... title=.... id url title 1 "/users/" "查看用戶" 2 "/users/add/" "添加用戶" 3 "/customer/add" "添加客戶" UserInfor_permission id user_id permission_id id user_id permission_id 1 1 1 2 1 2 3 2 2 4 3 1 5 3 2 6 3 3 4 4 1 5 4 2 6 4 3 4 5 1 5 5 2 6 5 3 4 6 1 5 6 2 6 6 3 4 7 1 5 7 2 6 7 3 示例:登陸人:egon 訪問url:http://127.0.0.1:8000/users/ def users(request): user_id=request.session.get("user_id") obj=UserInfor.objects.filter(pk=user_id).first() obj.permission.all().valuelist("url") return HttpResponse("users.....") # 版本2: UserInfor name pwd roles name pwd egon 123 alex 456 alex 456 alex 456 alex 456 alex 456 alex 456 alex 456 alex 456 Role title=....... permissions=...... id title 1 銷售員 UserInfor2Role id user_id role_id 1 1 1 Permission url=..... title=.... id url title 1 "/users/" "查看用戶" 2 "/users/add/" "添加用戶" 3 "/customer/add" "添加客戶" Role2Permission id role_id permission_id 1 1 1 2 1 2 3 1 3 3 rbac(role-based access control) 關於rbac: (1) 建立表關係: class User(models.Model): name=models.CharField(max_length=32) pwd=models.CharField(max_length=32) roles=models.ManyToManyField(to="Role") def __str__(self): return self.name class Role(models.Model): title=models.CharField(max_length=32) permissions=models.ManyToManyField(to="Permission") def __str__(self): return self.title class Permission(models.Model): title=models.CharField(max_length=32) url=models.CharField(max_length=32) def __str__(self):return self.title (2) 基於admin錄入數據 (3) 登陸校驗: if 登陸成功: 查詢當前登陸用戶的權限列表註冊到session中 (4) 校驗權限(中間件的應用) class ValidPermission(MiddlewareMixin): def process_request(self,request): # 當前訪問路徑 current_path = request.path_info # 檢查是否屬於白名單 valid_url_list=["/login/","/reg/","/admin/.*"] for valid_url in valid_url_list: ret=re.match(valid_url,current_path) if ret: return None # 校驗是否登陸 user_id=request.session.get("user_id") if not user_id: return redirect("/login/") # 校驗權限 permission_list = request.session.get("permission_list",[]) # ['/users/', '/users/add', '/users/delete/(\\d+)', 'users/edit/(\\d+)'] flag = False for permission in permission_list: permission = "^%s$" % permission ret = re.match(permission, current_path) if ret: flag = True break if not flag: return HttpResponse("沒有訪問權限!") return None
權限粒度控制 簡單控制: {% if "users/add" in permissions_list%} 擺脫表控制 更改數據庫結構 class Permission(models.Model): title=models.CharField(max_length=32) url=models.CharField(max_length=32) action=models.CharField(max_length=32,default="") group=models.ForeignKey("PermissionGroup",default=1) def __str__(self):return self.title class PermissionGroup(models.Model): title = models.CharField(max_length=32) def __str__(self): return self.title 登陸驗證: permissions = user.roles.all().values("permissions__url","permissions__group_id","permissions__action").distinct() 構建permission_dict permissions: [ {'permissions__url': '/users/add/', 'permissions__group_id': 1, 'permissions__action': 'add'}, {'permissions__url': '/roles/', 'permissions__group_id': 2, 'permissions__action': 'list'}, {'permissions__url': '/users/delete/(\\d+)', 'permissions__group_id': 1, 'permissions__action': 'delete'}, {'permissions__url': 'users/edit/(\\d+)', 'permissions__group_id': 1, 'permissions__action': 'edit'} ] permission_dict { 1: { 'urls': ['/users/', '/users/add/', '/users/delete/(\\d+)', 'users/edit/(\\d+)'], 'actions': ['list', 'add', 'delete', 'edit']}, 2: { 'urls': ['/roles/'], 'actions': ['list']} } 中間價校驗權限: permission_dict=request.session.get("permission_dict") for item in permission_dict.values(): urls=item['urls'] for reg in urls: reg="^%s$"%reg ret=re.match(reg,current_path) if ret: print("actions",item['actions']) request.actions=item['actions'] return None return HttpResponse("沒有訪問權限!")
原生form forms組件 ChoiceField(Field) ModelChoiceField(ChoiceField) ModelMultipleChoiceField(ModelChoiceField) 1 針對form表單設計form組件 modelform class Book(models.Model): title=models.CharField(max_length=32) price=models.DecimalField(max_digits=8,decimal_places=2) # 999999.99 date=models.DateField() publish=models.ForeignKey("Publish") authors=models.ManyToManyField("Author") class BookForm(forms.Form): title = forms.CharField(max_length=32,label="書籍名稱") price = forms.DecimalField(max_digits=8, decimal_places=2,label="價格") # 999999.99 date = forms.DateField(label="日期", widget=widgets.TextInput(attrs={"type":"date"}) ) #gender=forms.ChoiceField(choices=((1,"男"),(2,"女"),(3,"其餘"))) #publish=forms.ChoiceField(choices=Publish.objects.all().values_list("pk","title")) publish=forms.ModelChoiceField(queryset=Publish.objects.all()) authors=forms.ModelMultipleChoiceField(queryset=Author.objects.all())