django權限管理

當咱們爲應用建立一個Models, 在同步到數據庫裏,django默認給了三個權限 ,就是 add, change, delete權限。html

首先,咱們建立一個perm_test的project, 而後再建立一個school的app.python

django-admin.py startproject perm_test
cd perm_test
python manage.py startapp school

models:web

from django.db import models

# Create your models here.

class Student(models.Model):
    name = models.CharField('姓名', max_length=64)
    age = models.SmallIntegerField('年齡')
    choices = (
        (1, ''),
        (2, ''),
        (3, '未知')
    )
    sex = models.SmallIntegerField('性別', choices=choices)

admin.pyshell

from django.contrib import admin

# Register your models here.
from . import models

admin.site.register(models.Student)

同步到數據庫並建立superuser:數據庫

python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser

啓動web服務,登陸admin(http://localhost:8000django

python manage.py runserver

在後臺先建立一個用戶試試, 看到選擇權限的地方以下:app

image

先不加任何權限保存後,用新用戶登陸admin:post

image

直接提示無權修改任何東西,由於沒有任何權限。this

嘗試增長一個Student的change的權限,刷新一下:url

image

只有修改的權限, 由於咱們加的就是修改的權限, 可是這裏好你有刪除選項,執行試一下

image

沒法顯示,顯然是沒有權限 刪除的

image

到django shell裏查詢一下權限:

>>> python manage.py shell
>>> from django.contrib.auth.models import User
>>> user_obj = User.objects.get(name='lishi')
#可使用dir來看有哪些方法能夠用
>>> dir(user_obj)
#獲取用戶的全部權限
>>> user_obj.get_all_permissions()
{'school.change_student'}

以上這些都是django內置的權限, 那咱們怎麼來定義本身的權限呢?

 

下面來定義本身的權限 並應用在本身的頁面上呢?

首先要說的是,咱們必須爲url設置name, 由於權限須要和urlname配合使用,urlname就是url(r’’, views.method, name=’urlname’)裏的name值。還要創建權限名稱和具體操做的映射關係, 即權限名稱與(urlname, 請求方法,參數列表)的對應關係,若是用字典表示,就是這樣的:

{'add student', 'get', []}

第一步,要在models中創建權限的名稱和描述信息,這個信息是在django admin中設置權限時顯示的信息

第二步,創建一個權限表Permission, 將權限的名稱,url名稱,請求方法(get or post), 參數列表保存進去

第三步, 定義判斷權限的方法

下面來實驗一下,咱們定義一個查看學員列表的權限:

第一步: 在models中創建權限表,我是將映射關係存放在數據庫中:

class Permission(models.Model):
    name = models.CharField("權限名稱", max_length=64)
    url = models.CharField('URL名稱', max_length=255)
    chioces = ((1, 'GET'), (2, 'POST'))
    per_method = models.SmallIntegerField('請求方法', choices=chioces, default=1)
    argument_list = models.CharField('參數列表', max_length=255, help_text='多個參數之間用英文半角逗號隔開', blank=True, null=True)
    describe = models.CharField('描述', max_length=255)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = '權限表'
        verbose_name_plural = verbose_name
        #權限信息,這裏定義的權限的名字,後面是描述信息,描述信息是在django admin中顯示權限用的
        permissions = (
            ('views_student_list', '查看學員信息表'),
            ('views_student_info', '查看學員詳細信息'),
        )

第二步:在權限表中添加內容,將對應權限寫入數據庫:

image

 

第三步: 定義權限驗證方法, 邏輯是這樣,請求訪問學員列表, 先獲取url地址,根據url地址獲得urlname, 再獲取請求方法和參數,而後使用urlname, 請求方法,參數列表到數據庫中查詢,能查詢到以後說明這個權限存在;而後再使用request.user.has_perm()來判斷該用戶是否具備該權限。

在應用school目錄下創建permission.py文件,咱們將權限驗證方法寫在這裏面:

from django.shortcuts import render
from school import models
from django.db.models import Q
from django.core.urlresolvers import resolve   #此方法能夠將url地址轉換成url的name

def perm_check(request, *args, **kwargs):
    url_obj = resolve(request.path_info)
    url_name = url_obj.url_name
    perm_name = ''
    #權限必須和urlname配合使得
    if url_name:
        #獲取請求方法,和請求參數
        url_method, url_args = request.method, request.GET
        url_args_list = []
        #將各個參數的值用逗號隔開組成字符串,由於數據庫中是這樣存的
        for i in url_args:
            url_args_list.append(str(url_args[i]))
        url_args_list = ','.join(url_args_list)
        #操做數據庫
        get_perm = models.Permission.objects.filter(Q(url=url_name) and Q(per_method=url_method) and Q(argument_list=url_args_list))
        if get_perm:
            for i in get_perm:
                perm_name = i.name
                perm_str = 'school.%s' % perm_name
                if request.user.has_perm(perm_str):
                    print('====》權限已匹配')
                    return True
            else:
                print('---->權限沒有匹配')
                return False
        else:
            return False
    else:
        return False   #沒有權限設置,默認不放過


def check_permission(fun):    #定義一個裝飾器,在views中應用
    def wapper(request, *args, **kwargs):
        if perm_check(request, *args, **kwargs):  #調用上面的權限驗證方法
            return fun(request, *args, **kwargs)
        return render(request, '403.html', locals())
    return wapper

到這裏自定義權限已經完成了,接下來要作的是在咱們本身的頁面中使用:

建立一個student_list.html頁面,展現學員列表:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
  <table>
      <tr>
          <td>姓名</td>
          <td>年齡</td>
          <td>性別</td>
      </tr>
      {% for student_obj in students_obj %}
      <tr>
          <td>{{ student_obj.name }}</td>
          <td>{{ student_obj.age }}</td>
          <td>{{ student_obj.get_sex_display }}</td>
      </tr>
      {% endfor %}
  </table>
</body>
</html>

建立views方法:

from django.shortcuts import render
from school import models
from school.permission import  check_permission
# Create your views here.

@check_permission
def students(request):
    students_obj = models.Student.objects.all()
    return render(request, 'students_list.html', locals())

咱們使用裝飾器的方法來檢查權限。當用戶具備權限時,返回渲染的頁面。但彷佛還少了點什麼,在權限驗證方法裏,當檢測沒有權限時返加403頁面,因此咱們還要建立一個403頁面403.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>403</h1>
    <h2>You don't have enought permissions to this action!</h2>
</body>
</html>

最後創建urls.py吧:

project下的urls.py:

from django.conf.urls import url, include
from django.contrib import admin


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^school/', include('school.urls')),
]

school下的urls.py:

from django.conf.urls import url
from school import views


urlpatterns = [
    url(r'students/$', views.students, name='students_list'),
]

到這算是徹底寫好了,下面來驗證一下:

登陸admin設置一下lishi的權限,咱們先不給任何權限,訪問http://localhost:8000/school/students看看結果:

image

訪問結果, 是咱們想要的結果,提示沒有權限:

image

再給lishi一個查看的權限:

image

再來訪問一下:

image

到此爲止吧.

相關文章
相關標籤/搜索