91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用django-guardian實現django-admin的行級權限控制的方法

發布時間:2020-10-10 22:37:15 來源:腳本之家 閱讀:297 作者:Darcy''s Blog 欄目:開發技術

用django框架來做一些后臺管理的web頁面簡直太方便了,django自帶模塊級的權限系統,用來做一些內部的系統非常合適,可以大大的減少開發量。但是django自帶的權限系統還不支持行級的權限控制,如果要實現行級的權限控制,需要依賴第三方的app來開發,或者自己重新寫一個。

需求描述

我們項目組開發的一些系統通常會用mysql數據庫來存儲一些配置,但是如果每次有配置修改的時候都去手動修改mysql數據的話,會挺麻煩的,同時也比較容易出錯。django-admin能夠根據定義的model自動的生成相應的頁面,同時還能提供權限的管理,所以我們就把一些系統到的配置放到django中。但是到現在,隨著系統的需求越來越多,該系統已經不止我們自己項目組的人員使用,也要開放給其他項目組的同事使用,所以就產生了一些更細粒度的權限需求。因此,我們要在現有的系統上支持行級的權限控制。

解決方案

當然可以自己寫一套權限系統了,但是自己寫的成本比較高,而且自己寫的不一定比較好。所以我就先在網上找了一些現成的解決方案, https://djangopackages.org/grids/g/perms/ 該鏈接列出了現有的一些第三方的權限系統解決方案。從該頁面來看,django-guardian是最受歡迎的第三方權限系統,而且支持行級的權限系統,同時還可以整合到django-admin里面,所以我就選擇了django-guardian。

關鍵步驟

安裝配置django-guardian

安裝配置django-guardian比較簡單,按照她項目提供的 文檔 進行安裝就可以了,安裝完成后會在數據庫里面創建兩張權限相關的表。

把django-guardian整合到django-admin

首先把admin.py文件里面需要用到行級權限的類,由原來的繼承admin.ModelAdmin,改成繼承GuardedModelAdmin,這時候打開某個數據行的頁面的時候,在該頁面的右上角的歷史旁邊會顯示編輯對象權限的按鈕,點擊該按鈕進去相應的頁面就可以編輯該行數據的具體權限。

配置完權限的時候,用一個新的用戶測試的話,會發現該用戶沒有權限來訪問任何的數據,這是因為GuardedModelAdmin還有很多事情沒有幫我們做,我們還需要重寫一些函數來實現admin后臺頁面的顯示。具體的信息看下面的代碼注釋。

from guardian.admin import GuardedModelAdmin
from guardian.shortcuts import get_objects_for_user, assign_perm, remove_perm, get_users_with_perms, \
  get_groups_with_perms
  
# 需改前
@admin.register(DataAssistantJob)
class DataAssistantJobAdmin(admin.ModelAdmin):
  pass

# 修改后
@admin.register(DataAssistantJob)
class DataAssistantJobAdmin(GuardedModelAdmin):
  # app是否在主頁面中顯示的話由該函數決定
  def has_module_permission(self, request):
    if super().has_module_permission(request):
      return True
    return self.get_model_objs(request).exists()

  # 在顯示數據列表額時候,哪些數據顯示,哪些不顯示,由該函數控制
  def get_queryset(self, request):
    if request.user.is_superuser:
      return super().get_queryset(request)

    data = self.get_model_objs(request)
    return data
    
  # 內部用來獲取某個用戶有權限訪問的數據行
  def get_model_objs(self, request, action=None, klass=None):
    opts = self.opts
    actions = [action] if action else ['view', 'change', 'delete']
    klass = klass if klass else opts.model
    model_name = klass._meta.model_name
    return get_objects_for_user(user=request.user, perms=[f'{perm}_{model_name}' for perm in actions],
                  klass=klass, any_perm=True)

  # 用來判斷某個用戶是否有某個數據行的權限
  def has_perm(self, request, obj, action):
    opts = self.opts
    codename = f'{action}_{opts.model_name}'
    if obj:
      return request.user.has_perm(f'{opts.app_label}.{codename}', obj)
    else:
      return self.get_model_objs(request, action).exists()

  # 是否有查看某個數據行的權限
  def has_view_permission(self, request, obj=None):
    return self.has_perm(request, obj, 'view')

  # 是否有修改某個數據行的權限
  def has_change_permission(self, request, obj=None):
    return self.has_perm(request, obj, 'change')

  # 是否有刪除某個數據行的權限
  def has_delete_permission(self, request, obj=None):
    return self.has_perm(request, obj, 'delete')

  # 用戶應該擁有他新增的數據行的所有權限
  def save_model(self, request, obj, form, change):
    result = super().save_model(request, obj, form, change)
    if not request.user.is_superuser and not change:
      opts = self.opts
      actions = ['view', 'add', 'change', 'delete']
      [assign_perm(f'{opts.app_label}.{action}_{opts.model_name}', request.user, obj) for action in actions]
    return result

通過上面的修改,django-admin中的模塊就能夠支持行級的權限,并能夠正確的在后臺頁面中顯示出來,當然如果有很多的模塊需要支持行級的權限控制,則可以把上面的這些修改寫到一個新的類中,然后其他想支持行級權限的模塊再從該模塊繼承就可以了。

總結

感覺django-guardian和django-admin整合,實現的不是很好。如果開發者對django內部的代碼不怎么了解,那么用django-guardian來實現行級權限控制的話會挺麻煩的,個人認為django-guardian完全可以把和django-admin的整合做到開箱即用的效果,就像django自帶的權限系統一樣。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

古蔺县| 霍林郭勒市| 教育| 江源县| 连平县| 长海县| 琼海市| 昌都县| 且末县| 潞西市| 华宁县| 武威市| 安龙县| 南部县| 绩溪县| 革吉县| 金乡县| 吉安县| 亚东县| 崇义县| 离岛区| 常州市| 玉溪市| 伊宁县| 龙井市| 常德市| 昭通市| 同心县| 教育| 库伦旗| 高淳县| 陆良县| 故城县| 磐石市| 嘉峪关市| 杭锦旗| 油尖旺区| 荔波县| 逊克县| 二连浩特市| 涞源县|