Django權限之 樹形菜單權限構建


菜單權限

  左側欄展示用戶擁有的權限

1, 重構stark組件 ,加上title和左側欄

  創建base.html,靜態文件

  

  {%block css%}

  盒子,繼承的頁面要繼承這個模板,他有自己的CSS,為了擴充css用的

   {%endblock%}

2,更改編輯和刪除按鈕的圖標

   圖標網址: font awespme 這個網站的圖標比較豐富

  copy到自己的stark-->sites.py , 也要引這個插件才能用

    

  list_view.html 要繼承 base.html

    兩個盒子

    

 

    

 3, 做添加頁面

  add_view.html 繼承 base.html

   

  編輯和刪除頁面 同上操作 .

4, base.html---> {% side_bar %} 左邊欄 

  構建左側權限標簽(動態構建, "路徑","文本")

  注意!!

    動態參數的不能做菜單權限,能做菜單權限的只有查看

    查看客戶和查看訂單注意兩個方面: 1, 文本要展示出來, 2,過濾出來真正的菜單權限,

  之前在permissions.py錄入的數據,有url,沒有title,就沒辦法做文本了,不要用這個列表,用字典. 

   

  更改:

    在去base.html  

  

再去登錄頁面前 要去改 middlewares.py中間件,

  

登錄頁面后,頁面是這樣的

   

  出現了8個,但我們只要兩個; 進行過濾,

  定義: 查看訂單和查看客戶為菜單權限,其他為按鈕權限

  重新設計Permission表字段

    數據遷移>>>>>  查看更改數據庫 

 

再回到 permissions.py 進行  篩選 ,  添加  : 

 

再去stark組件 >>> sites.py>>> list_view視圖中,進行判斷篩選

  

 然后在 base.html 中 side_bar 循環 menu_list :

  重新進行登錄和查看 

\  

現在出現了一個惡心的事,剛剛的操作 動了stark >>> sites  的源碼.

  后果是 菜單權限   只有在 list_view 視圖中才會顯示,每個視圖都寫一份也能實現, 但代碼重復,也不能動源碼.

這個用自定義標簽過濾器方法 :

  在 rbac >>> 建一個templatetags >>> rbac.py  (寫自定義模板)

  在 rbac >>> 建一個templates >>> menu.html   (menu 模板)

構建自定義I標簽:

  以上在  list_view 視圖中 寫的函數 寫在 templatetags >>> rbac.py 中 ,因為這是跟權限相關的 

     語法 :    @register.inclusion_tag() 括號里放 樣式,傳給誰用的

  流程 :  templatetags >>> rbac.py(構建數據)  傳給  templates >>> menu.html(渲染出來兩個a 'or' p標簽) 

      最終到  base.html       *這樣數據 , 樣式 就都在rbac 中了  , 耦合性好

  最后 ,按照加載應用從上到下的順序,為了避免 menu.html 被上邊的應用重復后覆蓋,在

      templates >>> 建 rbac的包, 在把 menu.html 放進去. 

 templatetags >>> rbac.py(構建數據)

from django import template   
from ..models import Permission
register = template.Library()


@register.inclusion_tag("rbac/menu.html")
def get_menu(request):
    print("OK...")
    permission_list = request.session.get("permission_list")
    menu_list = []
    for per in permission_list:
        if per.get("type") == "menu":
            menu_list.append(per)


    default_data=[
                      {
                        "text": '信息管理',
                        "href": '',
                        "tags": ['2'],
                        "nodes": [
                          {
                            "text": '客戶管理',
                            "href": '',
                             "tags": ['1'],
                             "nodes": [
                              {
                                "text": '查看客戶',
                                  "href": '/stark/app01/customer/',
                                  "tags": ['0']
                              },
                            ]
                          },
                          {
                              "text": '訂單管理',
                              "href": '',
                              "tags": ['1'],
                              "nodes": [
                              {
                                  "text": '查看訂單',
                                  "href": '/stark/app01/order/',
                                  "tags": ['0']
                              },
                            ]
                          },
                        ]
                      },

                      {
                          "text": '權限管理',
                          "href": '',
                          "tags": ['0']
                      },

                    ]
    return {"default_data": default_data}

 templates >>>rbac>>>> menu.html

  <div id="treeview" class="small">

  </div>



<script src="/static/bootstrap-treeview/js/bootstrap-treeview.js"></script>
<script type="text/javascript">
    // API文檔參數列表: https://www.cnblogs.com/tangzeqi/p/8021637.html

              $(function() {

                  var options = {             #safe:不加這個瀏覽器會轉義
                        data:{{ default_data|safe }} , //data屬性是必須的,是一個對象數組    Array of Objects.
                        color: "", //所有節點使用的默認前景色,這個顏色會被節點數據上的backColor屬性覆蓋.        String
                        backColor: "#000000", //所有節點使用的默認背景色,這個顏色會被節點數據上的backColor屬性覆蓋.     String
                        borderColor: "#000000", //邊框顏色。如果不想要可見的邊框,則可以設置showBorder為false。        String
                        nodeIcon: "glyphicon glyphicon-stop", //所有節點的默認圖標
                        checkedIcon: "glyphicon glyphicon-check", //節點被選中時顯示的圖標         String
                        collapseIcon: "glyphicon glyphicon-minus", //節點被折疊時顯示的圖標        String
                        expandIcon: "glyphicon glyphicon-plus", //節點展開時顯示的圖標        String
                        emptyIcon: "glyphicon", //當節點沒有子節點的時候顯示的圖標              String
                        enableLinks: false, //是否將節點文本呈現為超鏈接。前提是在每個節點基礎上,必須在數據結構中提供href值。        Boolean
                        highlightSearchResults: true, //是否高亮顯示被選中的節點        Boolean
                        levels: 2, //設置整棵樹的層級數  Integer
                        multiSelect: false, //是否可以同時選擇多個節點      Boolean
                        onhoverColor: "#F5F5F5", //光標停在節點上激活的默認背景色      String
                        selectedIcon: "glyphicon glyphicon-stop", //節點被選中時顯示的圖標     String

                        searchResultBackColor: "", //當節點被選中時的背景色
                        searchResultColor: "", //當節點被選中時的前景色

                        selectedBackColor: "", //當節點被選中時的背景色
                        selectedColor: "#FFFFFF", //當節點被選中時的前景色

                        showBorder: true, //是否在節點周圍顯示邊框
                        showCheckbox: false, //是否在節點上顯示復選框
                        showIcon: true, //是否顯示節點圖標
                        showTags: false, //是否顯示每個節點右側的標記。前提是這個標記必須在每個節點基礎上提供數據結構中的值。
                        uncheckedIcon: "glyphicon glyphicon-unchecked", //未選中的復選框時顯示的圖標,可以與showCheckbox一起使用
                    };

                    $('#treeview').treeview({

                          color: "#4F4F4F",
                          expandIcon: 'glyphicon glyphicon-chevron-right',
                          collapseIcon: 'glyphicon glyphicon-chevron-down',
                          nodeIcon: 'glyphicon glyphicon-bookmark',
                          enableLinks: true,
                          levels: 1,
                          showIcon:false,
                          selectedBackColor: "",
                          selectedColor: "#333",
                          data: {{ default_data|safe }},
                    });


                    $('#treeview').on('nodeSelected',function(event, data) {
                        console.log(data);
                    })


          });
</script>

 base.html 獲取到數據

<div class="pg-body">

        <div class="left-menu">
             {% block side_bar %}
              {% load rbac %}

              {% get_menu request %}

             {% endblock side_bar %}
        </div>

    <div class="right-body">
         {% block content %}

         {% endblock content %}
    </div>
</div>

 

補充 : 

  多級菜單 展示

  一級菜菜單沒有URL  二級也沒有  ,最后一級有URL, 也就是它的父級都沒有URL

  權限與權限之間建立父子關系 , 自關聯的東東 , 一個父權限有多個子權限.一個子權限只能有一個父權限

  

  在權限的 model 中建立字段 

   在加一個 blank=True 默認為空   ,        數    據    遷    移

  默認為True,在頁面就可以寫URL就可以不寫

 

  在 rbac >>> stark.py 中加展示 

   

登錄后 進入 permissions 加點權限

 

查看訂單  改成 訂單管理 下

 

下邊構建樹形數據結構 ,

    templatetags >>> rbac.py(構建數據) 里 

    是一個列表,一個權限放在一個字典中

     treeview5 :>> 是標簽div的名字,找到這個標簽

       text : 標簽構建的文本

      href : 路徑

      tags : 有多少的子節點 ,就是就幾個兒子  

      nodes : 是它下邊的兒子,下邊幾個字典就幾個兒子

    menu.html 就不要自己寫了,用插件寫 , 引 static 組件,

    menu.html插件需要的數據,rbac提供數據( menu插件要求的 default_data 格式是:

              (   一個列表套一個字典,字典里代表有權限的URL                 tags, nodes 里套幾個兒子              )

  

  

 

 

 

 

 

 

 

 

 

 

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM