欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Django 內置權限擴展案例詳解

 更新時間:2019年03月04日 10:29:32   作者:37丫37  
這篇文章主要介紹了Django 內置權限擴展案例詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

當Django的內置權限無法滿足需求的時候就自己擴展吧~

背景介紹

overmind項目使用了Django內置的權限系統(tǒng),Django內置權限系統(tǒng)基于model層做控制,新的model創(chuàng)建后會默認新建三個權限,分別為:add、change、delete,如果給用戶或組賦予delete的權限,那么用戶將可以刪除這個model下的所有數(shù)據(jù)。

原本overmind只管理了我們自己部門的數(shù)據(jù)庫,權限設置只針對具體的功能不針對細粒度的數(shù)據(jù)庫實例,例如用戶A 有審核的權限,那么用戶A 可以審核所有的DB,此時使用內置的權限系統(tǒng)就可以滿足需求了,但隨著系統(tǒng)的不斷完善要接入其他部門的數(shù)據(jù)庫管理,這就要求針對不同用戶開放不同DB的權限了,例如A部門的用戶只能操作A部門的DB,Django內置基于model的權限無法滿足需求了。

實現(xiàn)過程

先來確定下需求:

1.  保持原本的基于功能的權限控制不變,例如用戶A有查詢權限,B有審核權限

2.  增加針對DB實例的權限控制,例如用戶A只能查詢特定的DB,B只能審核特定的DB

對于上邊需求1用內置的權限系統(tǒng)已經(jīng)可以實現(xiàn),這里不贅述,重點看下需求2,DB信息都存放在同一個表里,不同用戶能操作不同的DB,也就是需要把每一條DB信息與有權限操作的用戶進行關聯(lián),為了方便操作,我們考慮把DB跟用戶組關聯(lián),在用戶組里的用戶都有權限,而操作類型經(jīng)過分析主要有兩類讀和寫,那么需要給每個MySQL實例添加兩個字段分別記錄對此實例有讀和寫權限的用戶組

如下代碼在原來的model基礎上添加 read_groupswrite_groups 字段,DB實例跟用戶組應是ManyToManyField多對多關系,一個實例可以關聯(lián)多個用戶組,一個用戶組也可以屬于多個實例

class Mysql(models.Model):
 Env = (
 (1, 'Dev'),
 (2, 'Qa'),
 (3, 'Prod'),
 )
 create_time = models.DateTimeField(auto_now_add=True, verbose_name='創(chuàng)建時間')
 update_time = models.DateTimeField(auto_now=True, verbose_name='更新時間')

 project_id = models.IntegerField(verbose_name='項目')
 project_tmp = models.CharField(max_length=128, default='')
 environment = models.IntegerField(choices=Env, verbose_name='環(huán)境')

 master_host = models.GenericIPAddressField(verbose_name='master主機')
 master_port = models.IntegerField(default=3306, verbose_name='master端口')

 slave_host = models.GenericIPAddressField(null=True, verbose_name='slave主機')
 slave_port = models.IntegerField(null=True, default=3306, verbose_name='slave端口')

 database = models.CharField(max_length=64, verbose_name='數(shù)據(jù)庫')

 read_groups = models.ManyToManyField(Group, related_name='read', verbose_name='讀權限')
 write_groups = models.ManyToManyField(Group, related_name='write', verbose_name='寫權限')

 description = models.TextField(null=True, verbose_name='備注')

model確定了,接下來我們分三部分詳細介紹下權限驗證的具體實現(xiàn)

列表頁權限控制

如上圖列表頁,每個用戶進入系統(tǒng)后只能查看自己有讀權限的MySQL實例列表,管理員能查看所有,代碼如下:

def mysql(request):
 if request.method == 'GET':
 if request.user.is_superuser:
 _lists = Mysql.objects.all().order_by('id')
 else:
 # 獲取登錄用戶的所有組
 _user_groups = request.user.groups.all()

 # 構造一個空的QuerySet然后合并
 _lists = Mysql.objects.none()
 for group in _user_groups:
 _lists = _lists | group.read.all()

 return render(request, 'overmind/mysql.index.html', {'request': request, 'lPage': _lists})

實現(xiàn)的思路是:獲取登錄用戶的所有組,然后循環(huán)查詢每個組有讀取權限的數(shù)據(jù)庫實例,最后把每個組有權限讀的數(shù)據(jù)庫實例進行合并返回

獲取登錄用戶的所有組用到了ManyToMany的查詢方法: request.user.groups.all()

最終返回的一個結果是QuerySet,所以我們需要先構造一個空的Queryset: Mysql.objects.none()

QuerySet合并不能用簡單的相加,應為: QuerySet-1 | QuerySet-2

查詢接口權限控制

如上圖系統(tǒng)中有很多功能是需要根據(jù)項目、環(huán)境查詢對應的DB信息的,對于此類接口也需要控制用戶只能查詢自己有權限讀的DB實例,管理員能查看所有,代碼如下:

def get_project_database(request, project, environment):
 if request.method == 'GET':
 _jsondata = {}

 if request.user.is_superuser:
 # 返回所有項目和環(huán)境匹配的DB
 _lists = Mysql.objects.filter(
 project_id=int(project),
 environment=int(environment)
 )

 _jsondata = {i.id: i.database for i in _lists}
 else:
 # 只返回用戶有權限查詢的DB
 _user_groups = request.user.groups.all()

 for group in _user_groups:
 # 循環(huán)mysql表中有read_groups權限的所有組
 for mysql in group.read.all():
  if mysql.project_id == int(project) and mysql.environment == int(environment):
  _jsondata[mysql.id] = mysql.database

 return JsonResponse(_jsondata)

實現(xiàn)思路與上邊類似,只是多了一步根據(jù)項目和環(huán)境再進行判斷

需要根據(jù)group去反查都有哪些DB實例包含了該組,這里用到了M2M的related_name屬性: group.read.all()

更多關于Django ORM查詢的內容可以看這篇文章 Django model select的各種用法詳解 有詳細的總結

執(zhí)行操作權限控制

除了上邊的兩個場景之外我們還需要在執(zhí)行具體的操作之前去判斷是否有權限,例如執(zhí)行審核操作前判斷用戶是否對此DB有寫權限

有很多地方都需要做這個判斷,所以把這個權限判斷單獨寫個方法來處理,代碼如下:

def check_permission(perm, mysql, user):
 # 如果用戶是超級管理員則有權限
 if user.is_superuser:
 return True

 # 取出用戶所屬的所有組
 _user_groups = user.groups.all()

 # 取出Mysql對應權限的所有組
 if perm == 'read':
 _mysql_groups = mysql.read_groups.all()
 if perm == 'write':
 _mysql_groups = mysql.write_groups.all()

 # 用戶組和DB權限組取交集,有則表示有權限,否則沒有權限
 group_list = list(set(_user_groups).intersection(set(_mysql_groups)))

 return False if len(group_list) == 0 else True

實現(xiàn)思路是:根據(jù)傳入的第三個用戶參數(shù),來獲取到用戶所有的組,然后根據(jù)傳入的第一個參數(shù)類型讀取或寫入和第二個參數(shù)DB實例來獲取到有權限的所有組,然后對兩個組取交集,交集不為空則表示有權限,為空則沒有

M2M的 .all() 取出來的結果是個list,兩個list取交集的方法為: list(set(list-A).intersection(set(list-B)))

view中使用就很簡單了,如下:

def query(request):
 if request.method == 'POST':
 postdata = request.body.decode('utf-8')
 _host = get_object_or_404(Mysql, id=int(postdata.get('database')))

 # 檢查用戶是否有DB的查詢權限
 if check_permission('read', _host, request.user) == False:
 return JsonResponse({'state': 0, 'message': '當前用戶沒有查詢此DB的權限'})

寫在最后

1.  Django有第三方的基于object的權限管理模塊Django-guardian,本項目沒有使用主要是因為一來權限需求并不復雜,自己實現(xiàn)也很方便,二來個人在非必要的情況下并不喜歡引用過多第三方的包,后續(xù)升級維護都是負擔

2.  方案和代碼不盡完美,各位有更好的方案建議或更優(yōu)雅的代碼寫法歡迎與我交流

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

相關文章

  • allure結合python生成測試報告教程

    allure結合python生成測試報告教程

    這篇文章主要介紹了allure結合python生成測試報告教程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • python實現(xiàn)五子棋程序

    python實現(xiàn)五子棋程序

    這篇文章主要為大家詳細介紹了python實現(xiàn)五子棋程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • python 中Arduino串口傳輸數(shù)據(jù)到電腦并保存至excel表格

    python 中Arduino串口傳輸數(shù)據(jù)到電腦并保存至excel表格

    這篇文章主要介紹了python Arduino串口傳輸數(shù)據(jù)到電腦并保存至excel表格,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-10-10
  • python樹莓派通過隊列實現(xiàn)進程交互的程序分析

    python樹莓派通過隊列實現(xiàn)進程交互的程序分析

    這篇博客就結合實際的python程序通過隊列實現(xiàn)進程交互,通過程序分析需要的庫函數(shù),對python樹莓派進程交互相關知識感興趣的朋友一起看看吧
    2021-07-07
  • python CMD命令行傳參實現(xiàn)方法(argparse、click、fire)

    python CMD命令行傳參實現(xiàn)方法(argparse、click、fire)

    這篇文章主要介紹了python CMD命令行傳參實現(xiàn)方法(argparse、click、fire),本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-07-07
  • python實現(xiàn)門限回歸方式

    python實現(xiàn)門限回歸方式

    今天小編就為大家分享一篇python實現(xiàn)門限回歸方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • Python MNIST手寫體識別詳解與試練

    Python MNIST手寫體識別詳解與試練

    MNIST(官方網(wǎng)站)是非常有名的手寫體數(shù)字識別數(shù)據(jù)集,在Tensorflow的官方網(wǎng)站里,第一個就拿它來做實戰(zhàn)講解,咱們也以此作為開始的項目
    2021-11-11
  • 在python中利用GDAL對tif文件進行讀寫的方法

    在python中利用GDAL對tif文件進行讀寫的方法

    今天小編就為大家分享一篇在python中利用GDAL對tif文件進行讀寫的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-11-11
  • Python3.5面向對象與繼承圖文實例詳解

    Python3.5面向對象與繼承圖文實例詳解

    這篇文章主要介紹了Python3.5面向對象與繼承,結合圖文與實例形式詳細分析了Python3.5面向對象與繼承的相關概念、原理、實現(xiàn)方法及操作注意事項,需要的朋友可以參考下
    2019-04-04
  • python+opencv像素的加減和加權操作的實現(xiàn)

    python+opencv像素的加減和加權操作的實現(xiàn)

    這篇文章主要介紹了python+opencv像素的加減和加權操作的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-07-07

最新評論