侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Django用户认证系统 组与权限解析

框架(架构)  /  管理员 发布于 7年前   164

Django的权限系统很简单,它可以赋予users或groups中的users以权限。

Django admin后台就使用了该权限系统,不过也可以用到你自己的代码中。

User对象具有两个ManyToManyField字段,groups和user_permissions

groups = models.ManyToManyField(Group, verbose_name=_('groups'),  blank=True, help_text=_('The groups this user belongs to. A user will '  'get all permissions granted to each of '  'their groups.'),  related_name="user_set", related_query_name="user")user_permissions = models.ManyToManyField(Permission,  verbose_name=_('user permissions'), blank=True,  help_text=_('Specific permissions for this user.'),  related_name="user_set", related_query_name="user")

可以像其它的django Model一样来访问他们:

myuser.groups = [group_list]myuser.groups.add(group, group, ...)myuser.groups.remove(group, group, ...)myuser.groups.clear()myuser.user_permissions = [permission_list]myuser.user_permissions.add(permission, permission, ...)myuser.user_permissions.remove(permission, permission, ...)myuser.user_permissions.clear()

权限Permissions

权限是作为一个Model存在的,建立一个权限就是创建一个Permission Model的实例。

@python_2_unicode_compatibleclass Permission(models.Model):  """  The permissions system provides a way to assign permissions to specific  users and groups of users.   The permission system is used by the Django admin site, but may also be  useful in your own code. The Django admin site uses permissions as follows:     - The "add" permission limits the user's ability to view the "add" form     and add an object.    - The "change" permission limits a user's ability to view the change     list, view the "change" form and change an object.    - The "delete" permission limits the ability to delete an object.   Permissions are set globally per type of object, not per specific object  instance. It is possible to say "Mary may change news stories," but it's  not currently possible to say "Mary may change news stories, but only the  ones she created herself" or "Mary may only change news stories that have a  certain status or publication date."   Three basic permissions -- add, change and delete -- are automatically  created for each Django model.  """  name = models.CharField(_('name'), max_length=255)  content_type = models.ForeignKey(ContentType)  codename = models.CharField(_('codename'), max_length=100)  objects = PermissionManager()   class Meta:    verbose_name = _('permission')    verbose_name_plural = _('permissions')    unique_together = (('content_type', 'codename'),)    ordering = ('content_type__app_label', 'content_type__model',          'codename')   def __str__(self):    return "%s | %s | %s" % (      six.text_type(self.content_type.app_label),      six.text_type(self.content_type),      six.text_type(self.name))   def natural_key(self):    return (self.codename,) + self.content_type.natural_key()  natural_key.dependencies = ['contenttypes.contenttype']

字段fields

name:必需。50个字符或更少,例如,'Can Vote‘

content_type:必需,一个对于django_content_type数据库table的引用,table中含有每个应用中的Model的记录。

codename:必需,100个字符或更少,例如,'can_vote'。

如果要为某个Model创建权限:

from django.db import models class Vote(models.Model):  ...   class Meta:    permissions = (("can_vote", "Can Vote"),)

如果这个Model在应用foo中,则权限表示为'foo.can_vote',检查某个用户是否具有权限myuser.has_perm('foo.can_vote')

默认权限default permissions

如果已经在 INSTALLED_APPS配置了django.contrib.auth,它会保证为installed applications中的每个Django Model创建3个缺省权限:add, change 和 delete。

这些权限会在你第一次运行 manage.py migrate(1.7之前为syncdb) 时创建。当时所有的models都会建立权限。在这之后创建的新models会在再次运行 manage.py migrate时创建这些默认权限。这些权限与admin管理界面中的创建,删除,修改行为是一一对应的。

假设你有一个应用 foo ,其中有一个模型 Bar, 你可以用下述方法来测试基本权限:

  • add: user.has_perm('foo.add_bar')
  • change: user.has_perm('foo.change_bar')
  • delete: user.has_perm('foo.delete_bar')

权限模型( Permission model)一般不直接使用。

组Groups

组也是作为Model存在的:

@python_2_unicode_compatibleclass Group(models.Model):  """  Groups are a generic way of categorizing users to apply permissions, or  some other label, to those users. A user can belong to any number of  groups.   A user in a group automatically has all the permissions granted to that  group. For example, if the group Site editors has the permission  can_edit_home_page, any user in that group will have that permission.   Beyond permissions, groups are a convenient way to categorize users to  apply some label, or extended functionality, to them. For example, you  could create a group 'Special users', and you could write code that would  do special things to those users -- such as giving them access to a  members-only portion of your site, or sending them members-only email  messages.  """  name = models.CharField(_('name'), max_length=80, unique=True)  permissions = models.ManyToManyField(Permission,    verbose_name=_('permissions'), blank=True)   objects = GroupManager()   class Meta:    verbose_name = _('group')    verbose_name_plural = _('groups')   def __str__(self):    return self.name   def natural_key(self):    return (self.name,)

字段fields:

name:必需,80个字符或更少,例如, 'Awesome Users'。

permissions:ManyToManyField to Permission

group.permissions = [permission_list]group.permissions.add(permission, permission, ...)group.permissions.remove(permission, permission, ...)group.permissions.clear()

Programmatically creating permissions

除了可以使用Model meta来创建权限,也可以直接用代码创建。

例如,为myapp应用中的BlogPost模型创建一个can_publish权限:

from myapp.models import BlogPostfrom django.contrib.auth.models import Group, Permissionfrom django.contrib.contenttypes.models import ContentType content_type = ContentType.objects.get_for_model(BlogPost)permission = Permission.objects.create(codename='can_publish',        name='Can Publish Posts',        content_type=content_type)

权限可以被赋予一个User对象通过它的user_permissions属性或者赋予一个Group通过它的permissions属性。

权限缓存

User的权限检查时是可以被缓存的,如果一个新权限被赋予一个User,如果再立即检查是不会被检查出来的。最简单的方法是重新fetch User对象。

from django.contrib.auth.models import Permission, Userfrom django.shortcuts import get_object_or_404 def user_gains_perms(request, user_id):  user = get_object_or_404(User, pk=user_id)  #权限检查会缓存现在的权限集  user.has_perm('myapp.change_bar')   permission = Permission.objects.get(codename='change_bar')  user.user_permissions.add(permission)   # 检查权限缓存集  user.has_perm('myapp.change_bar') # False   # 请求新实例  user = get_object_or_404(User, pk=user_id)   # Permission cache is repopulated from the database  user.has_perm('myapp.change_bar') # True   ...

权限装饰器

permission_required(perm[, login_url=None, raise_exception=False])

检查用户是否具有某个权限,类似于@login_required()

from django.contrib.auth.decorators import permission_required@permission_required('polls.can_vote', login_url='/loginpage/')def my_view(request):  ...

模板中的权限

user的的权限保存在模板变量 {{ perms }}中,是django.contrib.auth.context_processors.PermWrapper实例。

{{ perms.foo }}

上面的单属性是User.has_module_perms的代理。如果user拥有foo中的任一权限,则为True

{{ perms.foo.can_vote }}

上面的两级属性查询是User.has_perm的代理,如果用户拥有foo.can_vote权限则为True。

例如:

{% if perms.foo %}  <p>You have permission to do something in the foo app.</p>  {% if perms.foo.can_vote %}    <p>You can vote!</p>  {% endif %}  {% if perms.foo.can_drive %}    <p>You can drive!</p>  {% endif %}{% else %}  <p>You don't have permission to do anything in the foo app.</p>{% endif %}

或者:

{% if 'foo' in perms %}  {% if 'foo.can_vote' in perms %}    <p>In lookup works, too.</p>  {% endif %}{% endif %}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


  • 上一条:
    Django文件存储 默认存储系统解析
    下一条:
    Django用户认证系统 Web请求中的认证解析
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Filament v3.1版本发布(0个评论)
    • docker + gitea搭建一个git服务器流程步骤(0个评论)
    • websocket的三种架构方式使用优缺点浅析(0个评论)
    • ubuntu20.4系统中宿主机安装nginx服务,docker容器中安装php8.2实现运行laravel10框架网站(0个评论)
    • phpstudy_pro(小皮面板)中安装最新php8.2.9版本流程步骤(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2018-05
    • 2020-02
    • 2020-03
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-11
    • 2021-03
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-08
    • 2023-08
    • 2023-10
    • 2023-12
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客