string(21) "{"docs":[],"count":0}" django权限管理 - 爱码网
huangxm

当我们为应用创建一个Models, 在同步到数据库里,django默认给了三个权限 ,就是 add, change, delete权限。

首先,我们创建一个perm_test的project, 然后再创建一个school的app.

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

models:

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.py

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:8000

python manage.py runserver

在后台先创建一个用户试试, 看到选择权限的地方如下:

image

先不加任何权限保存后,用新用户登录admin:

image

直接提示无权修改任何东西,因为没有任何权限。

尝试增加一个Student的change的权限,刷新一下:

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

到此为止吧.

分类:

技术点:

相关文章: