双层菜单细节完善
一.Queryset数据类型
1.可切片
2.可迭代
3.惰性查询:为了节省内存
book_list=Book.objects.all()惰性查询,先取出queryset但是不会立刻执行sql语句,什么时 候用什么时候执行
何时用到查询集:
print(book_list)
For...
切片
If book_list
4.缓存机制(缓存到内存)
book.objects.all()
简单的打印queryset不会缓存,执行两次sql语句
print(book_list)
print(book_list)
正常的会缓存
For obj in book_list
For obj in book_list
执行两次时,sql之执行一次
每个queryset会维持一个缓存空间,
优点:一次查询,多次使用
二. 缓存量大的问题解决方式:迭代器
Book.objects.all().iterator() #生成器对象 将queryset封装到生成器中
缺点:只能向下,只能用一次
三. 权限继续
1.二级菜单默认显示
在过滤器中:
1 @register.inclusion_tag("rbac/menu.html") 2 def get_menu_styles(request): 3 permission_menu_dict = request.session.get("permission_menu_dict") 4 print("permission_menu_dict",permission_menu_dict) 5 for val in permission_menu_dict.values(): 6 for item in val["children"]: 7 val["class"]="hide" 8 ret=re.search("^{}$".format(item["url"]),request.path) 9 if ret: 10 val["class"]="" #为permission_menu_dict增加一个字段class 11 return {"permission_menu_dict":permission_menu_dict}
在与过滤器对应的menu.html中:
1 <div class="multi-menu"> 2 {% for item in permission_menu_dict.values %} 3 <div class="item"> 4 <div class="title"><i class="{{ item.menu_icon }}"></i>{{ item.menu_title }}</div> 5 <div class="body {{ item.class }}"> #为body添加hide类名 6 {% for foo in item.children %} 7 <a href="{{ foo.url }}">{{ foo.title }}</a> 8 {% endfor %} 9 </div> 10 </div> 11 {% endfor %} 12 </div>
2.没有权限的按钮不显示
做法一:给按钮的显示加一个判断
1 {% if "/customer/add/" in request.session.permission_list %} 2 <a class="btn btn-default" href="/customer/add/"> 3 <i class="fa fa-plus-square" aria-hidden="true"></i> 添加客户 4 </a> 5 {% endif %}
缺点:所有的按钮都要判断
做法二:.没有权限的按钮不显示(过滤器版本)
做法封装到一个过滤器中,避免代码冗余,前端在需要的地方调用即可
过滤器部分:
1 @register.filter 2 def has_permission(btn_url,request): 3 permission_names = request.session.get("permission_list") 4 return btn_url in permission_list
前端调用部分:
1 {% load web %} 2 {% if "/customer/add/"|has_permission:request %} 3 <a class="btn btn-default" href="/customer/add/"> 4 <i class="fa fa-plus-square" aria-hidden="true"></i> 添加客户 5 </a> 6 {% endif %}
删除,编辑部分:
表头:
1 {% if "/customer/edit/(?P<cid>\d+)/"|has_permission:request %} 2 <th>编辑</th> 3 {% endif %} 4 {% if "/customer/del/(?P<cid>\d+)/"|has_permission:request %} 5 <th>删除</th> 6 {% endif %}
表内容:
1 {% if "/customer/edit/(?P<cid>\d+)/"|has_permission:request %} 2 <td> 3 <a style="color: #333333;" href="/customer/edit/{{ row.id }}/"> 4 <i class="fa fa-edit" aria-hidden="true"></i></a> 5 </td> 6 {% endif %} 7 {% if "/customer/del/(?P<cid>\d+)/"|has_permission:request %} 8 <td> 9 <a style="color: #d9534f;" href="/customer/del/{{ row.id }}/"><i class="fa fa-trash-o"></i></a> 10 </td> 11 {% endif %}
缺点:做法麻烦
做法三:添加一个字段,以后用的时候就不用考虑路径的正则问题
给permision加一个别名字段 name
取出来并注入session
1 permission_names=[] 2 for item in permissions: 3 permission_names.append(item["permissions__name"])
过滤器中使用:
1 @register.filter 2 def has_permission(btn_url,request): 3 permission_names=request.session.get("permission_names") 4 print("permission_names",permission_names) 5 return btn_url in permission_names
前端使用:
1 {% if "customer_edit"|has_permission:request %} 2 <td> 3 <a style="color: #333333;" href="/customer/edit/{{ row.id }}/"> 4 <i class="fa fa-edit" aria-hidden="true"></i></a> 5 </td> 6 {% endif %} 7 {% if "customer_del"|has_permission:request %} 8 <td> 9 <a style="color: #d9534f;" href="/customer/del/{{ row.id }}/"><i class="fa fa-trash-o"></i></a> 10 </td> 11 {% endif %}
改变世界,改变自己!