關於自動化平臺的動態選單設計
最近幾天是馬不停蹄的做一些事情,今天計劃把通用功能的部分先改進一些,比如說選單的許可權配置。目前使用的方案是使用者可以看到所有的選單,如果沒有許可權,則返回一個許可權不足的頁面。
因為整個開發後面會有多個模組,而且有些功能其實放在一起會看起來有些龐大,所以我們可以做裁剪,就是你登入以後,你能看到你擁有許可權的選單。
事情可以天馬行空的想,但是落到實處做的時候,發現還是有一些差別。比如我考慮了幾個方案:
-
重寫目前的登入校驗邏輯,不使用預設的admin模板的使用者
-
複用已有的使用者模型,然後新增幾個定製欄位來滿足需求
根據目前的功能實現,如果重寫user的模型,會有較大的難度,所以第一點可行但是代價太高,第二點的考慮是使用者的密碼校驗一個是預設實現的邏輯,程式碼改動後會不穩定而且改動效率較低,因為原來的使用者是一個抽象類,需要重新改動,代價也不低。
所以,思來想去,怎麼做都代價不小,於是乎,換了一個思路。原來的邏輯是靜態的,根據提供的選單列表來得到一些可選的許可權,我們可以保留這個邏輯,重新定製一下選單的部分,選單和使用者為多對多的關係,原來的使用者表也不用改動,只需要定製關係表就可以了。
所以權衡再三的想法是如果沒許可權就不要直接看到選單,這部分的關係在多對多的對映中體現。
到了這個程度,其實就離具體實現不遠了,我們繼續來理一下。
系統中預設建立的使用者只有普通許可權,需要登入到系統啟用才可以使用,所以我們的系統的想法是不要求一步到位,類似於邀請制,指定的使用者才可以配置相應的許可權,所以不會出現一下子建立出來多個超級使用者的情況,原來的邏輯就不用改動,繼續保留。
在這個基礎上配置一個選單管理頁面,把每個選單的標題,url,對映資訊都和使用者對映起來。
前端顯示的部分則透過首頁的index.html根據使用者的資訊動態匹配得到一個較新的選單列表,意味著每個人看到的選單可能不同。
使用者和選單之間是多對多的關聯關係
所以Django中的models.py的內容如下:
class Menu(models.Model):
menu_type_choices = (
( 'dashborad', u'平臺看板') ,
( 'cmdb', u'資產管理') ,
( 'env_deploy', u'環境部署') ,
( 'backup', u'資料備份') ,
( 'recover', u'資料恢復') ,
( 'scheduler', u'任務排程') ,
( 'global_config', u'全域性配置') ,
( 'user_center', u'使用者中心') ,
)
server_status_choices = (
( '1', 'valid') ,
( '0', 'invalid') ,
)
menu_id = models.SmallIntegerField( primary_key= True,verbose_name= '選單ID')
menu_title = models.CharField( max_length= 50,verbose_name= '選單標題')
menu_url = models.CharField( max_length= 50,verbose_name= '選單URL',unique= False)
menu_level = models.SmallIntegerField( blank= True,null= False,verbose_name= '選單等級')
menu_parent_level = models.SmallIntegerField( blank= True,null= False,verbose_name= '選單父等級')
menu_style = models.CharField( max_length= 50,verbose_name= '選單選用的元件風格')
menu_type = models.CharField( max_length= 50,choices=menu_type_choices ,null= False,verbose_name= '選單大類')
create_date = models.DateTimeField( auto_now_add= True)
update_date = models.DateTimeField( auto_now_add= True)
user_role = models.ManyToManyField(User)
menu_status = models.SmallIntegerField( choices=server_status_choices ,null= False,verbose_name= '選單狀態')
class Meta:
db_table = 'menu'
permissions = (
( "can_read_menu", "讀取選單許可權") ,
( "can_change_menu", "更改選單許可權") ,
( "can_add_menu", "新增選單許可權") ,
( "can_delete_menu", "刪除選單許可權") ,
)
verbose_name = '選單配置'
verbose_name_plural = '選單配置'
ORM對映生成的SQL類似下面的形式:
BEGIN;
CREATE TABLE `menu` (`menu_id` smallint NOT NULL PRIMARY KEY , `menu_title` varchar( 50) NOT NULL , `menu_url` varchar( 50) NOT NULL , `menu_level` smallint NULL , `menu_parent_level` smallint NULL , `menu_style` varchar( 50) NOT NULL , `menu_type` smallint NOT NULL , `create_date` datetime( 6) NOT NULL , `update_date` datetime( 6) NOT NULL , `menu_status` smallint NOT NULL);
CREATE TABLE `menu_user_role` (` id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY , `menu_id` smallint NOT NULL , `user_id` integer NOT NULL , UNIQUE (`menu_id` , `user_id`));
ALTER TABLE `menu_user_role` ADD CONSTRAINT `menu_user_role_menu_id_15dc921823a77a3f_fk_menu_menu_id` FOREIGN KEY (`menu_id`) REFERENCES `menu` (`menu_id`);
ALTER TABLE `menu_user_role` ADD CONSTRAINT `menu_user_role_user_id_52439a830d70516d_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (` id`);
COMMIT;
有了這些基本的設計,我們來模擬測試一下,當前的menu為空。
>>> from django.contrib.auth.models import User
>>> from db_ops.models import Menu
>>> Menu.objects.all()
( 0.001) QUERY = u'SELECT "menu"."menu_id", "menu"."menu_title", "menu"."menu_url", "menu"."menu_level", "menu"."menu_parent_level", "menu"."menu_style", "menu"."menu_type", "menu"."create_date", "me
nu "."update_date ", "menu "."menu_status " FROM "menu " LIMIT 21' - PARAMS = (); args=()
[]
我們呼叫API生成一個user,一個menu資訊。
User.objects.create(password= 'admin2',is_superuser= 0,username= 'admin2',first_name= 'admin',last_name= 'admin',email= 'aa@aa.com',is_staff= 0,is_active= 1,date_joined= '2018-01-04')
Menu.objects.create( menu_id= 1,menu_title= '後設資料管理',menu_url= 'cmdb_manage',menu_level= 2,menu_parent_level= 1,menu_type= 'cmdb',create_date= '2018-01-04',update_date= '2018-01-04',menu_status= 1)
如果要做多對多的對映,則是使用add方法,注意生成的insert語句。
user = User.objects.get( pk= 2)
menu = Menu.objects.get( pk= 1) >>> menu.user_role.add(user)
( 0.000) QUERY = u'BEGIN' - PARAMS = (); args= None
( 0.000) QUERY = u'SELECT "menu_user_role"."user_id" FROM "menu_user_role" WHERE ("menu_user_role"."menu_id" = %s AND "menu_user_role"."user_id" IN (%s))' - PARAMS = ( 1, 2); args=( 1, 2)
( 0.081) QUERY = u'INSERT INTO "menu_user_role" ("menu_id", "user_id") SELECT %s AS "menu_id", %s AS "user_id"' - PARAMS = ( 1, 2); args=( 1, 2)
如果要查詢中間表的資料,可以做關聯,比如下面的形式。
>>>User.objects.filter( menu__user_role= 1)
後續繼續補充完善。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-2149781/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 關於自動化平臺的動態選單設計(二)
- 關於短視訊平臺原始碼動態廣場自動播放gif動圖原始碼
- UI自動化關鍵字驅動的簡單設計思路UI
- 自動化平臺中的ORM和許可權設計ORM
- 自動化平臺中維度設計的一點思考
- 自動化平臺的幾個小計劃
- 小米自動化運維平臺演進設計思路運維
- 自動化測試平臺設計與實現(一)
- 自動化測試平臺
- Web自動化測試平臺設計與落地-概覽Web
- 自動化測試平臺設計與實現(二、自動化測試用例物件設計實現、關鍵字物件設計與實現)物件
- 自動化運維平臺的實施計劃運維
- Robot Framework自動化測試框架核心指南-如何做好自動化測試平臺框架的設計Framework框架
- 關於介面測試——自動化框架的設計與實現框架
- 如何實現工具無關化?關於自動化測試指令碼的設計指令碼
- UI 自動化測試平臺UI
- 基於 Springboot+vue 的介面自動化平臺Spring BootVue
- 設計多裝置或者跨平臺的 app 如何進行自動化?APP
- 基於 Springboot+vue 的介面自動化平臺 (二)Spring BootVue
- Django 介面自動化測試平臺Django
- 基於LINUX平臺的自動化測試的研究與應用
- 自動化運維平臺的流程草圖運維
- 自動化平臺的嘗試和小結
- API自動化測試平臺,高效實現對API的自動化測試API
- 基於 HttpRunner 的介面自動化測試平臺宣講 (已落地)HTTP
- 用於工業自動化的高精度直線電機平臺
- 動態建立選單
- [opendx] 基於 appium 的移動端 UI 自動化測試平臺-介紹篇APPUI
- 活動運營自動化平臺實踐
- 自動化平臺開發小結(六)
- 自動化平臺開發小結(五)
- 自動化平臺開發小結(四)
- 自動化平臺開發小結(三)
- 基於 Springboot+layui 實現介面自動化平臺Spring BootUI
- 基於jquery-treeview的動態選單實現jQueryView
- 談談最近做的一個自動化平臺
- 自動化平臺開發的幾點總結
- 手自一體化的移動雲測試平臺建設方案