对Django中的权限和分组管理实例讲解
权限
Django中内置了权限的功能。他的权限都是针对表或者说是模型级别的。比如对某个模型上的数据是否可以进行增删改查操作。他不能针对数据级别的,比如对某个表中的某条数据能否进行增删改查操作(如果要实现数据级别的,考虑使用django-guardian)。创建完一个模型后,针对这个模型默认就有四种权限,分别是增/删/改/查。可以在执行完migrate命令后,查看数据库中的auth_permission表中的所有权限。
字段:
content_type_id:是一个外键,参考表是django_content_type这个表,django就是根据这个来找到某一个具体的模型的。
codename:表示权限的名字。
name:对该权限的描述。
添加权限
通过定义模型添加权限:
如果我们想要增加新的权限,比如查看某个模型的权限,那么我们可以在定义模型的时候在Meta中定义好。
classArticle(models.Model): title=models.CharField(max_length=100) content=models.TextField() author=models.CharField(max_length=20) classMeta: permissions=[ ('black_article','拉黑文章的权限'), ]
然后执行makemigrations和migrate命令,就添加好了这一条权限。我们可以数据库中的auth_permission表中看到我们添加的这一条权限。
通过代码来添加权限。
权限都是django.contrib.auth.Permission的实例。这个模型包含三个字段,name、codename以及content_type,其中的content_type表示这个permission是属于哪个app下的哪个models。
定义一个视图函数,然后写入代码:
fromdjango.httpimportHttpResponse from.modelsimportArticle fromdjango.contrib.auth.modelsimportPermission,ContentType #Createyourviewshere. defadd_permission(request): content_type=ContentType.objects.get_for_model(Article) permission=Permission.objects.create(codename='white_article',name='将文章加入白名单',content_type=content_type) returnHttpResponse('权限创建成功')
然后执行这个视图函数,就能够添加这个权限了。
注意: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('
6、myuser.get_all_permissons():获取所有的权限。
注意:
这个地方的User模型并不是我们自定义的User模型,而是Django内置的一个User模型,而我们自定义的模型是不能够这样进行操作的。django内置的User模型我们需要导入:fromdjango.contrib.auth.modelsimportUser。
现在,我们给User模型绑定Article模型的一些权限:
执行上面的add方法和remove方法后需要执行一下save()方法,否则将不能保存到数据库中去。
views中新建一个视图:
首先我们需要创建一个User用户:
fromdjango.contrib.auth.modelsimportPermission,ContentType,User defcreateUser(request): user=User.objects.create_user(username='xujin',email='qq@qq.com',password='111111') returnHttpResponse('用户创建成功')
然后对该用户的权限进行操作:
fromdjango.httpimportHttpResponse from.modelsimportArticle fromdjango.contrib.auth.modelsimportPermission,ContentType,User defoperate_permission(request): user=User.objects.first() content_type=ContentType.objects.get_for_model(Article) permissions=Permission.objects.filter(content_type=content_type) forpermissioninpermissions: print(permission) #添加权限 user.user_permissions.set(permissions) #清除所有的权限 #user.user_permissions.clear() #查看是否拥有某个权限 ifuser.has_perm('authority.view_article'): print('这个用户拥有view_article的权限') else: print('这个用户没有view_article的权限') returnHttpResponse('操作权限的视图')
权限限定装饰器:
我们可以判断某一个用户是否拥有某个权限,再对它判断是否可以访问某一个页面。
要判断某个用户是否拥有某个权限,我们首先得登录:
fromdjango.contrib.authimportauthenticate,login defmy_login(request): username='xujin' password='111111' #username和password输入正确后这里会返回一个User对象 user=authenticate(request,username=username,password=password) #判断是否有该用户 ifuser: #使用django内置的一个登录函数来登录,登录成功之后会设置一个session值 login(request,user) else: returnHttpResponse('用户名或密码错误')
然后我们再写入添加文章的函数视图:
defadd_article(request): #判断用户是否登录了,这里的用户是指后台管理员的用户,也就是Django的User模型中的用户 #而不是浏览网站的用户 #通过这个request.user.is_authenticated可以判断是否登录了 ifrequest.user.is_authenticated: print('已经登录了') #再判断是否拥有这个权限 ifrequest.user.has_perm('authority.add_article'): returnHttpResponse('添加文章的页面') else: #403表示没有权限的意思 returnHttpResponse('你没有访问该页面的权限',status=403) else: returnHttpResponse('你还没有登录,请登录!!!')
这样,我们就实现了对某个用户的权限限制了。
上面这种方法是我们自己手动实现的,Django也内置一个装饰器permission_required,来帮我们实现了这个功能:
fromdjango.contrib.auth.decoratorsimportpermission_required #login_url没有登录跳转至的页面 #raise_exception=True,当你没有权限访问这个页面的时候,就会抛出一个403错误 #如果我们在网站中写了403那个页面的话,就会重定向到403哪一个页面 @permission_required('front.add_article',login_url='front/login',raise_exception=True) defadd_article(request): #判断用户是否登录了,这里的用户是指后台管理员的用户,也就是Django的User模型中的用户 #而不是浏览网站的用户 #ifrequest.user.is_authenticated: #print('已经登录了') #ifrequest.user.has_perm('authority.add_article'): #returnHttpResponse('添加文章的页面') #else: ##403表示没有权限的意思 #returnHttpResponse('你没有访问该页面的权限',status=403) #else: #returnHttpResponse('你还没有登录,请登录!!!') returnHttpResponse('添加文章的页面')
这样,我们就不用写上面那么多代码了,只需要写入我们的主体函数就可以了。
注意:如果一个函数视图需要多个权限才能进入的话,我们可以将需要的权限放入一个列表中,然后再将这个列表放在装饰器中。这个时候如果我们手动实现这个装饰器的功能的话,就要使用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:某个用户上的所有分组。多对多的关系。
我们首先新建一个分组:
fromdjango.contrib.auth.modelsimportPermission,ContentType,Group from.modelsimportArticle defoperate_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) returnHttpResponse('操作分组')
这里我们就创建了一个运营的分组,并且将Article这个模型所有的权限都添加进去了。
然后我们可以查看我们的数据库中我们添加的信息。在表auth_group和auth_group_permissions中,因为group和permissions是一个多对多的关系,所以它们拥有一个中间表。
我们创建好了一个组,那么我们就需要添加一个用户进去了。
修改上面的函数为:
defoperate_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() returnHttpResponse('操作分组')
这样,我们就对运营这个组添加了一个用户进去了。
判断某个group下的某个用户的所有权限:
defoperate_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) returnHttpResponse('操作分组')
在模板中使用权限:
在settings.TEMPLATES.OPTIONS.context_processors下,因为添加了django.contrib.auth.context_processors.auth上下文处理器,因此在模板中可以直接通过perms来获取用户的所有权限。
我们新建一个index.html的文件,然后渲染一下这个页面:
Title 首页
{#如果拥有这个权限,我就显示这个标签#} {%ifperms.authority.add_article%}添加文章 {%endif%}