演示Django版本为当前最新版本v2.2html
当Django配置文件中的INSTALL_APPS
包含了django.contrib.auth
时,就默认启用了一个简单的权限系统,提供了为用户或组分配权限的方法前端
之因此说简单呢?主要是由于:git
也就是说,假若有一个Blog表,咱们能够赋予用户或组对Blog表有delete的权限,那么用户或组成员就能够删除所有Blog,是不能控制用户只能删除本身建立的blog的github
若是但愿用户只能删除本身建立的Blog,不能删除别人建立的Blog,这种需求Django默认的权限管理就没法实现了,须要用到object permission
对象权限,有第三方模块实现了对象权限,如django-guardian,你能够直接使用,或者也能够本身实现对象权限,具体思路可参考这篇文章:Django内置权限扩展案例django
add_
、修改change_
、删除delete_
、查看view_
,这些权限记录在Permission表中,表数据以下:默认权限的建立是经过Django的信号signals实现的,使用了post_migrate
信号,在每次执行migrate操做时都会为新的Model模型建立默认权限,关于Django的信号Signals介绍和使用能够查看这篇文章:Django使用Signals监测model字段变化发送通知,后端
默认的权限名字和描述都是英文的,且只有四个,若是你不想用默认的几个权限,想要自定义的话,能够这样作:架构
class Blog(models.Model): title = models.CharField(max_length=256, verbose_name='标题') content = models.TextField(blank=True, null=True, verbose_name='内容') class Meta: default_permissions = () permissions = ( ("change_blog", "修改博客"), ("delete_blog", "查看博客"), ("publish_blog", "发布博客"), )
default_permissions: 清空默认的权限app
permissions: 设置权限,内容是一个嵌套的列表,列表第一个字段是codename
,第二个字段为name
工具
注意:若是你使用了django默认的admin的话,建议保留4个默认权限,能够添加新权限post
若是你用了Django自带的admin,在migrate以后就能在admin的user和group两个表中看到新添加的权限了
固然你也能够在程序中来添加或修改权限
ops = User.objects.get(id=2) ops.user_permissions.add(25, 26) ops.user_permissions.set([26, 27]) ops.user_permissions.remove(26, 27) ops.user_permissions.clear()
coffee = Group.objects.get(id=1) coffee.permissions.add(25) coffee.permissions.set([26,27]) coffee.permissions.remove(25) coffee.permissions.clear()
其中add
为添加,set
为设置,remove
为移除,clear
为清空,add
跟set
的区别是add
会在原有权限的基础上加新权限,而set
会清空原有权限设置成新的权限,后边的参数25,26,27能够为Permission的ID或者是Permission对象,例如这样也是能够的:
p = Permission.objects.get(id=25) coffee.permissions.add(p)
给组赋予权限,组内的全部用户会自动的拥有该组的权限,例如用户ops-coffee
隶属于组SRE
,SRE
组对Blog表有修改权限,那么即使是没有单独给Y37
用户分配任何权限,他也会有对Blog表的修改权限
get_all_permissions()
列出用户的全部权限:
>>> User.objects.get(username='ops-coffee').get_all_permissions() {'blog.publish_blog', 'blog.delete_blog', 'auth.add_group', 'blog.change_blog'}
get_group_permissions()
列出用户所属组的权限:
>>> User.objects.get(username='ops-coffee').get_group_permissions() {'blog.publish_blog', 'blog.change_blog', 'blog.delete_blog'}
用户对象能够经过has_perm
方法来判断用户是否拥有某个权限:
>>> User.objects.get(username='ops-coffee').has_perm('blog.change_blog') True >>> User.objects.get(username='ops-coffee').has_perm('blog.delete_blog') True
has_perm 的参数由<app label>.<permission codename>
两部分组成,例如blog.delete_blog
表示的就是名字为blog
的APP下的delete_blog
权限
能够直接在view中经过if判断用户权限,例如:
def ops_coffee_view(request): if not request.user.has_perm('blog.change_blog') return HttpResponse('403 Forbidden')
为了方便,Django还提供了一个permission_required()
的装饰器,能够快速的来校验用户是否拥有特定的权限,用法以下:
@permission_required(perm, login_url=None, raise_exception=False)
三个参数的意思分别是:
perm: 必须有,权限名称,同has_perm
同样
login_url: 非必须,登录的url地址,当你没有权限时自动跳转到登录页,这里能够设置登录地址的url
reise_exception: 非必须,当为True时,若是用户没有权限,则不会跳转到登录页,而是引起PermissionDenied
错误,返回403 Forbidden
以下例子,判断用户是否有blog
的APP的change_blog
权限,若是没有则返回403错误
@permission_required('blog.change_blog', raise_exception=True) def ops_coffee_view(request): ...
当前登录用户的权限保存在模版变量{{ perms }}
中,能够在模版中经过if判断用户是否拥有相应的权限而开放对应的内容,例如对于侧边栏菜单只显示用户有权限访问的,就能够这么写:
{% if perms.cmdb.view_project %} <li><a href="{% url 'project-list-url' %}"></i> 项目列表</a></li> {% endif %} {% if perms.cmdb.view_service %} <li><a href="{% url 'service-list-url' %}"></i> 服务列表</a></li> {% endif %} {% if perms.cmdb.view_environment %} <li><a href="{% url 'environment-list-url' %}"></i> 环境列表</a></li> {% endif %}
至此,Django的默认权限系统介绍完成,默认权限在小型项目中能知足大部分的需求,若是对权限控制有更高的要求能够关注前文中介绍的django-guardian
项目或本身实现
相关文章推荐阅读:
原文出处:https://www.cnblogs.com/37Y37/p/11658651.html