django 自定义user使用权限管理模块
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了django 自定义user使用权限管理模块,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5877字,纯文字阅读大概需要9分钟。
内容图文
这篇文章主要是讲如何让自定义的user模块也能用到django.contrib.auth中的权限管理模块
看这篇文章之前请先看一下我前边的两篇文章,本文以这两篇文章为基础:
下边是一个大概的实现,后边再做详细分析:
1、user model自定义
class AbstractUser(models.Model): # 登录信息 id = models.AutoField(primary_key=True) staff = models.IntegerField(default=0, verbose_name=u'员工号') ename = models.CharField(max_length=30, null=False, blank=False, unique=True, verbose_name=u'英文名') cname = models.CharField(max_length=30, null=False, blank=True, verbose_name=u'中文名') deptid = models.IntegerField(default=0, verbose_name=u'部门ID') deptname = models.CharField(max_length=255, db_index=True, verbose_name=u'部门名') expiration = models.DateTimeField(null=True) last_login = models.DateTimeField(default=timezone.now) is_staff = True is_active = True USERNAME_FIELD = 'ename' REQUIRED_FIELDS = [] class Meta: verbose_name = 'user' verbose_name_plural = 'users' abstract = True def get_full_name(self): return u'%s(%s)' % (self.ename, self.cname) def get_short_name(self): return self.ename def get_username(self): return self.get_full_name() def __uincode__(self): return self.get_full_name() def is_anonymous(self): return False def is_authenticated(self): return True class User(AbstractUser, PermissionsMixin): # 组织架构信息 team_id = models.IntegerField(default=0, db_index=True, help_text=u'员工组织架构(id)', null=True) team_full_id = models.CharField(max_length=255, db_index=True, help_text=u'员工组织架构(路径)', null=True) # # 权限组信息 # groups = models.ManyToManyField(Group, help_text=u'员工所属用户组') class Meta: db_table = 'user' def has_group(self, group): if not self.is_active: return False if self.is_superuser: return True if not hasattr(self, '_group_cache'): self._group_cache = set([g.name for g in self.groups.all()]) return group in self._group_cache def __unicode__(self): return u'%s(%s)' % (self.ename, self.cname)记得到setting中设置AUTH_USER_MODEL 为自定义user类
2、添加自己的backend类:
class TicketBackend(object): def __init__(self): from soap import client self.passport = client.passport def authenticate(self, ticket=None): ''' 授权函数 ''' if ticket: User = get_user_model() data = self.passport.DecryptTicket(ticket) if not hasattr(data, 'LoginName'): return None #判断权限 if not AuthenticateJudge.hasAuthenticate(data.LoginName): return None if data: ename = unicode(data.LoginName) try: user = User.objects.get(ename=ename) except User.DoesNotExist: user = User() user.is_active = True user.update(data) user.save() return user return None def get_user(self, user_id): User = get_user_model() try: return User.objects.get(id=user_id) except User.DoesNotExist: return None def get_group_permissions(self, user_obj, obj=None): """ Returns a set of permission strings that this user has through his/her groups. """ if user_obj.is_anonymous() or obj is not None: return set() if not hasattr(user_obj, '_group_perm_cache'): if user_obj.is_superuser: perms = Permission.objects.all() else: user_groups_field = get_user_model()._meta.get_field('groups') user_groups_query = 'group__%s' % user_groups_field.related_query_name() perms = Permission.objects.filter(**{user_groups_query: user_obj}) perms = perms.values_list('content_type__app_label', 'codename').order_by() user_obj._group_perm_cache = set(["%s.%s" % (ct, name) for ct, name in perms]) return user_obj._group_perm_cache def get_all_permissions(self, user_obj, obj=None): if user_obj.is_anonymous() or obj is not None: return set() if not hasattr(user_obj, '_perm_cache'): user_obj._perm_cache = set(["%s.%s" % (p.content_type.app_label, p.codename) for p in user_obj.user_permissions.select_related()]) user_obj._perm_cache.update(self.get_group_permissions(user_obj)) return user_obj._perm_cache def has_perm(self, user_obj, perm, obj=None): if not user_obj.is_active: return False return perm in self.get_all_permissions(user_obj, obj) def has_module_perms(self, user_obj, app_label): """ Returns True if user_obj has any permissions in the given app_label. """ if not user_obj.is_active: return False for perm in self.get_all_permissions(user_obj): if perm[:perm.index('.')] == app_label: return True return False
3、修改settings.py中的AUTHENTICATION_BACKENDS,将授权、权限判断入口设为我们自己的backend类(其实这里可以有多个backend类共存,但是考虑到有些属性、函数对象可能在其他backend不存在而导致异常,所以注释掉系统默认的ModelBackend):
AUTHENTICATION_BACKENDS = [ # 自己的权限判断方法 'users.backend.TicketBackend', #系统的权限判断方法 # 'django.contrib.auth.backends.ModelBackend', ]
解析:
从《用源码告诉你django权限管理是怎么回事》中我们可以获知,不管是修饰符permission_required 还是 user_passes_test 都是通过调用user.has_perm函数进行权限验证的。为了支持这个接口,我们在自定义自己的AUTH_USER_MODEL类时,我们必须继承 PermissionsMixin 类,这样我们才能使用PermissionsMixin类中提供的函数,包括has_perm,从PermissionMixin的定义我们可以看到,继承了PermissionsMixin类就自动添加了groups、user_permissions属性,这些是使用PermissionsMixin中权限相关的函数所必须的
class PermissionsMixin(models.Model): """ A mixin class that adds the fields and methods necessary to support Django's Group and Permission model using the ModelBackend. """ is_superuser = models.BooleanField(_('superuser status'), default=False, help_text=_('Designates that this user has all permissions without ' 'explicitly assigning them.')) 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 ' 'his/her group.'), 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权限管理是怎么回事》中我们也可以看到通过调用系统的user.has_perm函数从settings.py中的AUTHENTICATION_BACKENDS 中找到相应的backend类,并调用其中的has_perm函数,所以我们需要编写我们自己的backend类,并注册到AUTHENTICATION_BACKENDS 中,这样下来我们就可以通过user.has_perm对我们自定义的user类进行权限验证、授权了。也可以直接调用修饰符:user_passes_test、permission_required。
原文:http://blog.csdn.net/yangyihongyangjiying/article/details/45623865
内容总结
以上是互联网集市为您收集整理的django 自定义user使用权限管理模块全部内容,希望文章能够帮你解决django 自定义user使用权限管理模块所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。