当咱们为应用建立一个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:8000)django
python manage.py runserver
在后台先建立一个用户试试, 看到选择权限的地方以下:app
先不加任何权限保存后,用新用户登陆admin:post
直接提示无权修改任何东西,由于没有任何权限。this
尝试增长一个Student的change的权限,刷新一下:url
只有修改的权限, 由于咱们加的就是修改的权限, 可是这里好你有删除选项,执行试一下
没法显示,显然是没有权限 删除的
到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', '查看学员详细信息'), )
第二步:在权限表中添加内容,将对应权限写入数据库:
第三步: 定义权限验证方法, 逻辑是这样,请求访问学员列表, 先获取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看看结果:
访问结果, 是咱们想要的结果,提示没有权限:
再给lishi一个查看的权限:
再来访问一下:
到此为止吧.