对Django中的权限和分组管理实例讲解


Posted in Python onAugust 16, 2019

权限

Django中内置了权限的功能。他的权限都是针对表或者说是模型级别的。比如对某个模型上的数据是否可以进行增删改查操作。他不能针对数据级别的,比如对某个表中的某条数据能否进行增删改查操作(如果要实现数据级别的,考虑使用django-guardian)。创建完一个模型后,针对这个模型默认就有四种权限,分别是增/删/改/查。可以在执行完migrate命令后,查看数据库中的auth_permission表中的所有权限。

字段:

content_type_id:是一个外键,参考表是django_content_type这个表,django就是根据这个来找到某一个具体的模型的。

codename: 表示权限的名字。

name: 对该权限的描述。

添加权限

通过定义模型添加权限:

如果我们想要增加新的权限,比如查看某个模型的权限,那么我们可以在定义模型的时候在Meta中定义好。

class Article(models.Model):
 title = models.CharField(max_length=100)
 content = models.TextField()
 author = models.CharField(max_length=20)

 class Meta:
 permissions = [
  ('black_article','拉黑文章的权限'),
 ]

然后执行makemigrations和migrate命令,就添加好了这一条权限。我们可以数据库中的auth_permission表中看到我们添加的这一条权限。

通过代码来添加权限。

权限都是django.contrib.auth.Permission的实例。这个模型包含三个字段,name、codename以及content_type,其中的content_type表示这个permission是属于哪个app下的哪个models。

定义一个视图函数,然后写入代码:

from django.http import HttpResponse
from .models import Article
from django.contrib.auth.models import Permission,ContentType

# Create your views here.
def add_permission(request):
 content_type = ContentType.objects.get_for_model(Article)
 permission = Permission.objects.create(codename='white_article',name='将文章加入白名单',content_type=content_type)
 return HttpResponse('权限创建成功')

然后执行这个视图函数,就能够添加这个权限了。

注意: name字段是不能有重复的,否则会报错。

用户与权限管理:

权限本身只是一个数据,必须和用户进行绑定,才能起到作用。User模型和权限之间的管理,可以通过以下几种方式来管理:

1、myuser.user_permissions.set(permission_list):直接给定一个权限的列表。

2、myuser.user_permissions.add(permission,permission,…):一个个添加权限。这里就不能传入一个列表了,只能一个一个的传入数据了。

3、myuser.user_permissions.remove(permission,permission,…):一个个删除权限。

4、myuser.user_permissions.clear():清除所有的权限。

5、myuser.has_perm('<app_name>.'):判断是否拥有某个权限。权限参数是一个字符串,格式是app_name.codename。

6、myuser.get_all_permissons():获取所有的权限。

注意:

这个地方的User模型并不是我们自定义的User模型,而是Django内置的一个User模型,而我们自定义的模型是不能够这样进行操作的。django内置的User模型我们需要导入:from django.contrib.auth.models import User。

现在,我们给User模型绑定Article模型的一些权限:

执行上面的add方法和remove方法后需要执行一下save()方法,否则将不能保存到数据库中去。

views中新建一个视图:

首先我们需要创建一个User用户:

from django.contrib.auth.models import Permission,ContentType,User
def createUser(request):
 user = User.objects.create_user(username='xujin',email='qq@qq.com',password='111111')
 return HttpResponse('用户创建成功')

然后对该用户的权限进行操作:

from django.http import HttpResponse
from .models import Article
from django.contrib.auth.models import Permission,ContentType,User

def operate_permission(request):
 user = User.objects.first()
 content_type = ContentType.objects.get_for_model(Article)
 permissions = Permission.objects.filter(content_type=content_type)
 for permission in permissions:
 print(permission)
 # 添加权限
 user.user_permissions.set(permissions)
 # 清除所有的权限
 # user.user_permissions.clear()
 # 查看是否拥有某个权限
 if user.has_perm('authority.view_article'):
 print('这个用户拥有view_article的权限')
 else:
 print('这个用户没有view_article的权限')
 return HttpResponse('操作权限的视图')

权限限定装饰器:

我们可以判断某一个用户是否拥有某个权限,再对它判断是否可以访问某一个页面。

要判断某个用户是否拥有某个权限,我们首先得登录:

from django.contrib.auth import authenticate,login
def my_login(request):
 username = 'xujin'
 password = '111111'
 # username和password输入正确后这里会返回一个User对象
 user = authenticate(request,username=username,password=password)
 # 判断是否有该用户
 if user:
 # 使用django内置的一个登录函数来登录,登录成功之后会设置一个session值
 login(request,user)
 else:
 return HttpResponse('用户名或密码错误')

然后我们再写入添加文章的函数视图:

def add_article(request):
 # 判断用户是否登录了,这里的用户是指后台管理员的用户,也就是Django的User模型中的用户
 # 而不是浏览网站的用户

 # 通过这个request.user.is_authenticated可以判断是否登录了
 if request.user.is_authenticated:
 print('已经登录了')
 # 再判断是否拥有这个权限
 if request.user.has_perm('authority.add_article'):
  return HttpResponse('添加文章的页面')
 else:
  # 403表示没有权限的意思
  return HttpResponse('你没有访问该页面的权限',status=403)
 else:
 return HttpResponse('你还没有登录,请登录!!!')

这样,我们就实现了对某个用户的权限限制了。

上面这种方法是我们自己手动实现的,Django也内置一个装饰器permission_required,来帮我们实现了这个功能:

from django.contrib.auth.decorators import permission_required

# login_url没有登录跳转至的页面
# raise_exception=True,当你没有权限访问这个页面的时候,就会抛出一个403错误
# 如果我们在网站中写了403那个页面的话,就会重定向到403哪一个页面
@permission_required('front.add_article',login_url='front/login',raise_exception=True)
def add_article(request):
 # 判断用户是否登录了,这里的用户是指后台管理员的用户,也就是Django的User模型中的用户
 # 而不是浏览网站的用户
 # if request.user.is_authenticated:
 # print('已经登录了')
 # if request.user.has_perm('authority.add_article'):
 #  return HttpResponse('添加文章的页面')
 # else:
 #  # 403表示没有权限的意思
 #  return HttpResponse('你没有访问该页面的权限',status=403)
 # else:
 # return HttpResponse('你还没有登录,请登录!!!')
 return HttpResponse('添加文章的页面')

这样,我们就不用写上面那么多代码了,只需要写入我们的主体函数就可以了。

注意: 如果一个函数视图需要多个权限才能进入的话,我们可以将需要的权限放入一个列表中,然后再将这个列表放在装饰器中。这个时候如果我们手动实现这个装饰器的功能的话,就要使用has_perms方法来判断了。

分组:

权限有很多,一个模型就有最少四个权限,如果一些用户拥有相同的权限,那么每次都要重复添加。这时候分组就可以帮我们解决这种问题了,我们可以把一些权限归类,然后添加到某个分组中,之后再把和把需要赋予这些权限的用户添加到这个分组中,就比较好管理了。分组我们使用的是django.contrib.auth.models.Group模型, 每个用户组拥有id和name两个字段,该模型在数据库被映射为auth_group数据表。

分组操作:

Group.object.create(group_name):创建分组。

group.permissions:某个分组上的权限。多对多的关系。

group.permissions.add:添加权限。

group.permissions.remove:移除权限。

group.permissions.clear:清除所有权限。

user.get_group_permissions():获取用户所属组的权限。

user.groups:某个用户上的所有分组。多对多的关系。

我们首先新建一个分组:

from django.contrib.auth.models import Permission,ContentType,Group
from .models import Article

def operate_group(request):
 group = Group.objects.create(name='运营')
 # 额到Article这个模型的content_type_id
 content_type = ContentType.objects.get_for_model(Article)
 permissions = Permission.objects.filter(content_type=content_type)
 group.permissions.set(permissions)
 return HttpResponse('操作分组')

这里我们就创建了一个运营的分组,并且将Article这个模型所有的权限都添加进去了。

然后我们可以查看我们的数据库中我们添加的信息。在表auth_group和auth_group_permissions中,因为group和permissions是一个多对多的关系,所以它们拥有一个中间表。

我们创建好了一个组,那么我们就需要添加一个用户进去了。

修改上面的函数为:

def operate_group(request):
 # group = Group.objects.create(name='运营')
 # # 额到Article这个模型的content_type_id
 # content_type = ContentType.objects.get_for_model(Article)
 # permissions = Permission.objects.filter(content_type=content_type)
 # group.permissions.set(permissions)

 group = Group.objects.filter(name='运营').first()
 user = User.objects.first()
 user.groups.add(group)
 user.save()
 return HttpResponse('操作分组')

这样,我们就对运营这个组添加了一个用户进去了。

判断某个group下的某个用户的所有权限:

def operate_group(request):
 # group = Group.objects.create(name='运营')
 # # 额到Article这个模型的content_type_id
 # content_type = ContentType.objects.get_for_model(Article)
 # permissions = Permission.objects.filter(content_type=content_type)
 # group.permissions.set(permissions)

 # group = Group.objects.filter(name='运营').first()
 # user = User.objects.first()
 # user.groups.add(group)
 # user.save()

 user = User.objects.first()
 permissions = user.get_group_permissions()
 print(permissions)
 return HttpResponse('操作分组')

在模板中使用权限:

在settings.TEMPLATES.OPTIONS.context_processors下,因为添加了django.contrib.auth.context_processors.auth上下文处理器,因此在模板中可以直接通过perms来获取用户的所有权限。

我们新建一个index.html的文件,然后渲染一下这个页面:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<body>

<h1>首页</h1>
{#如果拥有这个权限,我就显示这个标签#}
{% if perms.authority.add_article %}
 <a href="#" rel="external nofollow" >添加文章</a>
{% endif %}

</body>
</html>

然后新建一个视图来渲染这个页面:

def index(request):
 return render(request,'index.html')

然后添加url,就可以了。当我们没有登录的时候,也不会显示出来。

以上这篇对Django中的权限和分组管理实例讲解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python下的twisted框架入门指引
Apr 15 Python
Python算法应用实战之队列详解
Feb 04 Python
Python信息抽取之乱码解决办法
Jun 29 Python
python 限制函数调用次数的实例讲解
Apr 21 Python
Python使用try except处理程序异常的三种常用方法分析
Sep 05 Python
Python Excel处理库openpyxl使用详解
May 09 Python
python 对字典按照value进行排序的方法
May 09 Python
在Mac中配置Python虚拟环境过程解析
Jun 22 Python
cookies应对python反爬虫知识点详解
Nov 25 Python
python爬虫泛滥的解决方法详解
Nov 25 Python
利用python进行文件操作
Dec 04 Python
基于Python的接口自动化读写excel文件的方法
Jan 15 Python
django创建最简单HTML页面跳转方法
Aug 16 #Python
在django中实现页面倒数几秒后自动跳转的例子
Aug 16 #Python
解决python3 安装不了PIL的问题
Aug 16 #Python
Python爬虫 批量爬取下载抖音视频代码实例
Aug 16 #Python
django 使用 PIL 压缩图片的例子
Aug 16 #Python
详解PyTorch手写数字识别(MNIST数据集)
Aug 16 #Python
Python 等分切分数据及规则命名的实例代码
Aug 16 #Python
You might like
php 删除记录实现代码
2009/03/12 PHP
探讨如何在PHP开启gzip页面压缩实例
2013/06/09 PHP
php利用cookies实现购物车的方法
2014/12/10 PHP
PHP抓取及分析网页的方法详解
2016/04/26 PHP
为调试JavaScript添加输出窗口的代码
2010/02/07 Javascript
用Juery网页选项卡实现代码
2011/06/13 Javascript
yepnope.js 异步加载资源文件
2011/09/08 Javascript
原生js编写设为首页兼容ie、火狐和谷歌
2014/06/05 Javascript
javascript轻量级模板引擎juicer使用指南
2014/06/22 Javascript
JS解析XML实例分析
2015/01/30 Javascript
jquery实现网页的页面平滑滚动效果代码
2015/11/02 Javascript
AngularJS中的$watch(),$digest()和$apply()区分
2016/04/04 Javascript
js中最容易被忽视的事件问题大总结
2016/05/15 Javascript
JavaScript算法系列之快速排序(Quicksort)算法实例详解
2016/09/04 Javascript
使用JS代码实现点击按钮下载文件
2016/11/12 Javascript
js实现不提示直接关闭网页窗口
2017/03/30 Javascript
JS+CSS实现下拉刷新/上拉加载插件
2017/03/31 Javascript
使用vue框架 Ajax获取数据列表并用BootStrap显示出来
2017/04/24 Javascript
详解基于vue-cli3.0如何构建功能完善的前端架子
2018/10/09 Javascript
详解nuxt 微信公众号支付遇到的问题与解决
2019/08/26 Javascript
浅谈layui数据表格判断问题(加入表单元素),设置单元格样式
2019/10/26 Javascript
vue中get请求如何传递数组参数的方法示例
2019/11/08 Javascript
Python中遍历字典过程中更改元素导致异常的解决方法
2016/05/12 Python
python编程实现希尔排序
2017/04/13 Python
python编写Logistic逻辑回归
2020/12/30 Python
Python实现检测文件MD5值的方法示例
2018/04/11 Python
从列表或字典创建Pandas的DataFrame对象的方法
2019/07/06 Python
解决Django后台ManyToManyField显示成Object的问题
2019/08/09 Python
印尼最大的婴儿用品购物网站:Orami
2017/09/28 全球购物
Lands’ End英国官方网站:高质量男女服装
2017/10/07 全球购物
西安当代医院管理研究院笔试题
2015/12/11 面试题
父亲追悼会答谢词
2014/01/17 职场文书
企业文化演讲稿
2014/05/20 职场文书
2014年工程工作总结
2014/11/25 职场文书
浅析Redis Sentinel 与 Redis Cluster
2021/06/24 Redis
Java实现扫雷游戏详细代码讲解
2022/05/25 Java/Android