上篇隨筆中,咱們實現了動態顯示一級菜單,如今考慮這樣一種狀況,用戶的菜單權限比較多,這個時候所有並列展示在左側菜單就不合適了,因此,如今有這樣一個需求,即把用戶的菜單權限分類,劃分紅二級菜單,動態顯示在左側菜單,解決方案以下:html
(1)分析需求,要求左側菜單以下顯示:前端
客戶管理:mysql
客戶列表sql
帳單管理:數據庫
帳單列表django
(2)修改rbac下的models.py,修改後代碼以下:session
from django.db import models class User(models.Model): """ 用戶表 """ name = models.CharField(verbose_name='用戶名', max_length=32) password = models.CharField(verbose_name='密碼', max_length=32) roles = models.ManyToManyField(verbose_name='擁有的全部角色', to='Role') def __str__(self): return self.name class Role(models.Model): """ 角色表 """ title = models.CharField(verbose_name='角色名稱', max_length=32) permissions = models.ManyToManyField(verbose_name='擁有的全部權限', to='Permission') def __str__(self): return self.title class Permission(models.Model): # 創建與菜單類的關聯,去掉is_menu和icon """ 權限表 """ url = models.CharField(verbose_name='含正則的URL', max_length=32) title = models.CharField(verbose_name='標題', max_length=32) menu = models.ForeignKey(verbose_name='所屬菜單', to="Menu", on_delete=models.CASCADE, null=True) def __str__(self): return self.title class Menu(models.Model): # 新增一個菜單表 title = models.CharField(max_length=32, verbose_name='菜單') icon = models.CharField(max_length=32, verbose_name='圖標', null=True, blank=True)
def initial_session(user_obj, request): """ 將當前登陸人的全部權限url列表和本身構建的全部菜單權限字典注入session :param user_obj: 當前登陸用戶對象 :param request: 請求對象HttpRequest """ # 查詢當前登陸人的全部權限列表 ret = Role.objects.filter(user=user_obj).values('permissions__url', 'permissions__title', 'permissions__menu__title', 'permissions__menu__icon', 'permissions__menu__id').distinct() permission_list = [] permission_menu_dict = {} for item in ret: # 獲取用戶權限列表用於中間件中權限校驗 permission_list.append(item['permissions__url']) menu_pk = item['permissions__menu__id'] if menu_pk: if menu_pk not in permission_menu_dict: permission_menu_dict[menu_pk] = { "menu_title": item["permissions__menu__title"], "menu_icon": item["permissions__menu__icon"], "children": [ { "title": item["permissions__title"], "url": item["permissions__url"], } ], } else: permission_menu_dict[menu_pk]["children"].append({ "title": item["permissions__title"], "url": item["permissions__url"], }) print('權限列表', permission_list) print('菜單權限', permission_menu_dict) # 將當前登陸人的權限列表注入session中 request.session['permission_list'] = permission_list # 將當前登陸人的菜單權限字典注入session中 request.session['permission_menu_dict'] = permission_menu_dict
from django.template import Library register =Library() @register.inclusion_tag("menu.html") def get_menu_styles(request): permission_menu_dict = request.session.get("permission_menu_dict") return {"permission_menu_dict": permission_menu_dict}
<div class="multi-menu"> {% for item in permission_menu_dict.values %} <div class="item"> <div class="title"> <i class="{{ item.menu_icon }}"></i>{{ item.menu_title }} </div> <div class="body"> {% for foo in item.children %} <a href="{{ foo.url }}">{{ foo.title }}</a> {% endfor %} </div> </div> {% endfor %} </div>
到此,二級菜單已經渲染到頁面中了,樣式或者其餘js效果就靠你的前端技術了!數據結構
咱們知道django項目使用數據庫要在settings.py中經過設置DATABASES給項目配置數據庫引擎,咱們以前都是給項目設置成MySQL或者django默認的sqlite3數據庫,你們知道一個項目能夠有多個應用,而且事實也是如此的,每一個項目下也會本身的模型類,按照以前的作法,在定義了數據庫引擎以後作數據庫遷移,那麼每一個app下的數據庫都使用settings中指定的數據庫了,可是你可能會有這樣的需求,就是不一樣的應用使用不一樣的數據庫,該如何作呢?沒錯,也是設置DATABASES,方式以下:app
DATABASES = { 'default': { # 下面沒有指定的都使用default下的數據庫引擎 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }, 'app01':{ # app01使用mysql數據庫引擎 'ENGINE': 'django.db.backends.mysql', 'NAME': 'bms', # 要鏈接的數據庫,鏈接前須要建立好 'USER': 'root', # 鏈接數據庫的用戶名 'PASSWORD': '', # 鏈接數據庫的密碼 'HOST': '127.0.0.1', # 鏈接主機,默認本機 'PORT': 3306 # 端口 默認3306 } }
二、ForeignKey的參數db_constraint解釋學習
在學習數據庫時,咱們經過定義外鍵使兩個表創建鏈接和約束,但有時咱們須要只創建鏈接,不創建約束,也就是經過在表中創建另外一個表的id,不設置foreignkey約束。
Django的ForeignKey也爲咱們想好了這兩種狀況:
(1)db_constraint = True 表示兩個表之間既創建了鏈接又有約束,並支持ORM語法查詢;
(2)db_constraint = False 表示兩個表之間只創建了鏈接,沒有創建約束,並支持ORM語法查詢;
注意:固然你可能會想到可否將ForeignKey改成一個IntegerField,經過定義IntegerField字段的值來與另外一個表創建聯繫,這種方法也沒錯,可是這樣就不能使用ORM語法查詢,也就享受不到ORM查詢的方便,爲開發形成了困難,因此不推薦這樣作!