權限控制到按鈕級別 :
1.思路 :
由於每個按鈕都能認為是一個權限,所以每個按鈕都會有一個自己的路徑,這些路徑都在用戶登錄時保存在了session中,django在渲染頁面之前先進行權限的匹配,如果用戶沒有某個按鈕的權限,那么這個按鈕就不會被渲染,從而實現權限的控制.
重點在於能快速的在session中搜索所有的用戶權限,之前在session中保存的數據是以一級菜單的id作為key,所以在遍歷時候會占用過多資源,而從數據庫中去找也比較浪費時間.所以可以在session中保存權限數據時就以定義的url別名來做key,這樣就可以快速匹配權限.
2.修改表結構,增加name字段保存路徑的別名 :
class Permission(models.Model):
'''
權限表
'''
url = models.CharField(max_length=256, verbose_name='權限', unique=True)
title = models.CharField(max_length=32, verbose_name='標題')
menu = models.ForeignKey('Menu', blank=True, null=True)
parent = models.ForeignKey('Permission', blank=True, null=True)
name = models.CharField(max_length=32, verbose_name='URL別名', unique=True)
def __str__(self):
return self.title
3.以上表中的別名字段作為key保存在session中,並保存pemissions__parent__name字段(因為當上表中的permissions__parent_id存在時,pemissions__parent__name即對應的二級權限的name).
for item in permission_query:
permission_dict[item['permissions__name']] = ({
'url':item['permissions__url'],
'pid':item['permissions__parent_id'],
'id': item['permissions__id'],
'title': item['permissions__title'],
'pname': item['permissions__parent__name']
})
4.通過自定義filter判斷是否顯示標簽 : (注意傳參)
@register.filter()
def has_permission(request,name):
if name in request.session.get(settings.PERMISSION_SESSION_KEY):
return True
5.在前端對每個按鈕做判斷 :
<td>
{% if request|has_permission:'customer_edit' %}
<a style="color: #333333;" href="/customer/edit/{{ row.id }}/">
<i class="fa fa-edit" aria-hidden="true"></i></a>
{% endif %}
{% if request|has_permission:'customer_del' %}
<a style="color: #d9534f;" href="/customer/del/{{ row.id }}/"><i
class="fa fa-trash-o"></i></a>
{% endif %}
</td>
6.注意對session數據變化帶來的錯誤做修改 :
for permission in permission_dict.values():
if re.match(r'^{}$'.format(permission['url']), url):
pid = permission.get('pid')
id = permission.get('id')
pname = permission.get('pname') #之前沒有
if pid:
request.current_menu_id = pid
request.breadcrumb_list.append(
{'title': permission_dict[pname]['title'], 'url': permission_dict[pname]['url']}) #之前為permission_dict[str(pid)]['']
request.breadcrumb_list.append({'title': permission['title'], 'url': permission['url']})
