成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Django中內(nèi)置權(quán)限擴(kuò)展的示例分析-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān)Django中內(nèi)置權(quán)限擴(kuò)展的示例分析,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

創(chuàng)新互聯(lián)從2013年創(chuàng)立,先為新沂等服務(wù)建站,新沂等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為新沂企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

背景介紹

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

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

實(shí)現(xiàn)過程

先來確定下需求:

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

2.  增加針對(duì)DB實(shí)例的權(quán)限控制,例如用戶A只能查詢特定的DB,B只能審核特定的DB

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

如下代碼在原來的model基礎(chǔ)上添加 read_groupswrite_groups 字段,DB實(shí)例跟用戶組應(yīng)是ManyToManyField多對(duì)多關(guān)系,一個(gè)實(shí)例可以關(guān)聯(lián)多個(gè)用戶組,一個(gè)用戶組也可以屬于多個(gè)實(shí)例

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

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

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

 slave_host = models.GenericIPAddressField(null=True, verbose_name='slave主機(jī)')
 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='讀權(quán)限')
 write_groups = models.ManyToManyField(Group, related_name='write', verbose_name='寫權(quán)限')

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

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

列表頁權(quán)限控制

Django中內(nèi)置權(quán)限擴(kuò)展的示例分析

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

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()

 # 構(gòu)造一個(gè)空的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})

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

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

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

QuerySet合并不能用簡(jiǎn)單的相加,應(yīng)為: QuerySet-1 | QuerySet-2

查詢接口權(quán)限控制

Django中內(nèi)置權(quán)限擴(kuò)展的示例分析

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

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

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

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

 for group in _user_groups:
 # 循環(huán)mysql表中有read_groups權(quán)限的所有組
 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)

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

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

更多關(guān)于Django ORM查詢的內(nèi)容可以看這篇文章 Django model select的各種用法詳解 有詳細(xì)的總結(jié)

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

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

有很多地方都需要做這個(gè)判斷,所以把這個(gè)權(quán)限判斷單獨(dú)寫個(gè)方法來處理,代碼如下:

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

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

 # 取出Mysql對(duì)應(yīng)權(quán)限的所有組
 if perm == 'read':
 _mysql_groups = mysql.read_groups.all()
 if perm == 'write':
 _mysql_groups = mysql.write_groups.all()

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

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

實(shí)現(xiàn)思路是:根據(jù)傳入的第三個(gè)用戶參數(shù),來獲取到用戶所有的組,然后根據(jù)傳入的第一個(gè)參數(shù)類型讀取或?qū)懭牒偷诙€(gè)參數(shù)DB實(shí)例來獲取到有權(quán)限的所有組,然后對(duì)兩個(gè)組取交集,交集不為空則表示有權(quán)限,為空則沒有

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

view中使用就很簡(jiǎn)單了,如下:

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的查詢權(quán)限
 if check_permission('read', _host, request.user) == False:
 return JsonResponse({'state': 0, 'message': '當(dāng)前用戶沒有查詢此DB的權(quán)限'})

關(guān)于“Django中內(nèi)置權(quán)限擴(kuò)展的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

網(wǎng)頁題目:Django中內(nèi)置權(quán)限擴(kuò)展的示例分析-創(chuàng)新互聯(lián)
網(wǎng)站網(wǎng)址:http://jinyejixie.com/article16/hgggg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、企業(yè)建站域名注冊(cè)、網(wǎng)站建設(shè)網(wǎng)站收錄、網(wǎng)站策劃

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)
庆阳市| 高碑店市| 稻城县| 梓潼县| 攀枝花市| 南通市| 二连浩特市| 略阳县| 棋牌| 海城市| 集安市| 河津市| 千阳县| 嘉黎县| 眉山市| 夏邑县| 新乐市| 阳朔县| 太湖县| 东乡| 云安县| 浮山县| 德江县| 额尔古纳市| 德安县| 论坛| 盐山县| 莒南县| 天柱县| 鄂伦春自治旗| 怀柔区| 钟祥市| 四会市| 稻城县| 贵德县| 陈巴尔虎旗| 湘潭市| 双峰县| 连平县| 虹口区| 呼和浩特市|