博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django中用户权限模块
阅读量:7084 次
发布时间:2019-06-28

本文共 9338 字,大约阅读时间需要 31 分钟。

Django中用户权限模块

1 auth模块

auth模块是Django提供的标准权限管理系统,可以提供用户身份认证, 用户组和权限管理。auth可以和admin模块配合使用, 快速建立网站的管理系统。在INSTALLED_APPS中添加'django.contrib.auth'使用该APP, auth模块默认启用。

2 User属性与方法

(1) 属性User是auth模块中维护用户信息的关系模式(继承了models.Model), 数据库中该表被命名为auth_user.参照后续源码更清楚的了解User类继承的属性与方法.这里只是展示一部分.该数据表在数据库中:'auth_user'    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,     "password" varchar(128) NOT NULL, "last_login" datetime NULL,     "is_superuser" bool NOT NULL,     "first_name" varchar(30) NOT NULL,     "last_name" varchar(30) NOT NULL,    "email" varchar(254) NOT NULL,     "is_staff" bool NOT NULL,     "is_active" bool NOT NULL,    "date_joined" datetime NOT NULL,    "username" varchar(30) NOT NULL UNIQUE一般当建立关联表时需要与User建立关联,则需要导入使用,比如建议OneToOne联系from django.contrib.auth.models import Userclass Profile(models.Model):    user = models.OneToOneField(User)  #建立关联到User    blog = models.CharField(maxlength=128, blank=True)    location = models.CharField(maxlength=128, blank=True)    occupation = models.CharField(maxlength=64, blank=True)(2) 方法is_anonymous():是否为匿名用户,如果你已经login,则这个方法返回始终为false.is_authenticated():是否通过验证,也就是通过用户名和密码判断该用户是否存在get_group_permissions():得到所有该用户所属组别的权限get_all_permissions():得到该用户所有的权限.has_perm(perm):判断用户是否具有特定权限,perm的格式是appname.codenameemail_user(subject, message, from_email=None):给某用户发送邮件例如创建一个superuser装饰器:#登录用户必须为超级用户,只能在类中使用def superuser_required(func):    def _wrapper(self,request,*args,**kwargs):        #User中包含了is_superuser属性        if not request.user.is_superuser:            #定义的未登录函数 not_authenticated()            return not_authenticated()        return func(self,request,*args,**kwargs)    return _wrapper这里设置superuser当然也可以自己设置不同权限的装饰器,这样代码更加简单!!

3 User常见的用法

(1)  新建用户user = User.objects.create_user(username, password)user.save()  #保存数据库auth模块不存储用户密码明文而是存储一个Hash值(2) 验证登录from django.contrib.auth import loginusername = request.POST['username']password = request.POST['password']#login不进行认证,也不检查is_active标志位, 一般和authenticate配合使用:user = authenticate(username=username, password=password)if not user:    if user.is_active:        return HttpResponse(json.dumps({          'error':'用户名或者密码错误'        }))login(request,user)login向session中添加SESSION_KEY, 便于对用户进行跟踪.首先我们要验证这个用户,然后再登陆,登陆成功后,我们可以通过request.user 来得到当前登陆的用户对象(3) 退出登录logout会移除request中user信息,并刷新session,清空cookie中sessionidfrom django.contrib.auth import logoutdef logout_view(request):    logout(request)(4) 限制非法用户访问普通做法通过 request.user.is_authenticated()判定,返回重定向login登录界面from django.http import HttpResponseRedirectdef my_view(request):    if not request.user.is_authenticated():        return HttpResponseRedirect('/login.html/')这种方法会造成重复判定问题简单做法采用装饰器语法糖搞定,django中封装了login_requiredfrom django.contrib.auth.decorators import login_required@login_required  #过滤掉非登录用户def my_view(request):    #限定为合法用户访问这样当你访问my_view的时候,就需要用户需要通过验证,不通过可以重定向来解决

4 Group用户组

django.contrib.auth.models.Group定义了用户组的模型, 每个用户组拥有id和name两个字段, 该模型在数据库被映射为auth_group数据表。User对象中有一个名为groups的多对多字段, 多对多关系由auth_user_groups数据表维护。Group对象可以通过user_set反向查询用户组中的用户。# 创建creategroup = Group.objects.create(name=group_name)group.save()#add用户加入用户组user.groups.add(group)或group.user_set.add(user)#remove用户退出用户组user.groups.remove(group)或group.user_set.remove(user)

5 Permission

Django的auth系统提供了模型级的权限控制, 即可以检查用户是否对某个数据表拥有增(add), 改(change), 删(delete)权限,但无法检查用户对某一篇博文是否拥有管理权限。user.has_perm('blog.add_article')user.has_perm('blog.change_article')user.has_perm('blog.delete_article')user.has_perm方法用于检查用户是否拥有操作某个模型权限,若拥有权限则返回True。仅是进行权限检查, 即是用户没有权限它也不会阻止程序员执行相关操作。permission_required修饰器可以代替has_perm并在用户没有相应权限时重定向到登录页或者抛出异常。# permission_required(perm[, login_url=None, raise_exception=False])#给blog中article添加权限,装饰器之后更加简单@permission_required('blog.add_article')def post_article(request):    pass

6 管理用户权限

User和Permission通过多对多字段user.user_permissions关联,在数据库中由auth_user_user_permissions数据表维护,可以执行添加权限,删除权限,清空权限.

7 User继承的父类

User先继承AbstractUser类,该类的基类为AbstractBaseUser,有兴趣的了解下,可以更深入的发现User类的功能

附上User继承类AbstractUser类的基类AbstractBaseUser的源码:class AbstractBaseUser(models.Model):    '''    常见的子类User继承的属性:    password    密码    last_login  最后登录    is_active   是否在线    常见定义的方法:    save  保存    is_authenticated  登录验证    set_password  设置密码    check_password   检查密码    '''    password = models.CharField(_('password'), max_length=128)    last_login = models.DateTimeField(_('last login'), blank=True, null=True)    is_active = True    REQUIRED_FIELDS = []    class Meta:        abstract = True    def get_username(self):        return getattr(self, self.USERNAME_FIELD)    def __init__(self, *args, **kwargs):        super(AbstractBaseUser, self).__init__(*args, **kwargs)        self._password = None    def __str__(self):        return self.get_username()    def clean(self):        setattr(self, self.USERNAME_FIELD, self.normalize_username(self.get_username()))    def save(self, *args, **kwargs):        super(AbstractBaseUser, self).save(*args, **kwargs)        if self._password is not None:            password_validation.password_changed(self._password, self)            self._password = None    def natural_key(self):        return (self.get_username(),)    @property    def is_anonymous(self):        """        Always return False. This is a way of comparing User objects to        anonymous users.        """        return CallableFalse    @property    def is_authenticated(self):        """        Always return True. This is a way to tell if the user has been        authenticated in templates.        """        return CallableTrue    def set_password(self, raw_password):        self.password = make_password(raw_password)        self._password = raw_password    def check_password(self, raw_password):        """        Return a boolean of whether the raw_password was correct. Handles        hashing formats behind the scenes.        """        def setter(raw_password):            self.set_password(raw_password)            # Password hash upgrades shouldn't be considered password changes.            self._password = None            self.save(update_fields=["password"])        return check_password(raw_password, self.password, setter)    def set_unusable_password(self):        # Set a value that will never be a valid hash        self.password = make_password(None)    def has_usable_password(self):        return is_password_usable(self.password)    def get_full_name(self):        raise NotImplementedError('subclasses of AbstractBaseUser must provide a get_full_name() method')    def get_short_name(self):        raise NotImplementedError('subclasses of AbstractBaseUser must provide a get_short_name() method.')    def get_session_auth_hash(self):        """        Return an HMAC of the password field.        """        key_salt = "django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash"        return salted_hmac(key_salt, self.password).hexdigest()    @classmethod    def get_email_field_name(cls):        try:            return cls.EMAIL_FIELD        except AttributeError:            return 'email'    @classmethod    def normalize_username(cls, username):        return unicodedata.normalize('NFKC', force_text(username))User继承类AbstractUser类的源码:class AbstractUser(AbstractBaseUser, PermissionsMixin):   '''   继承该类常见属性有:   username    用户名   first_name  姓   last_name   名   email       邮箱   '''    username_validator = UnicodeUsernameValidator() if six.PY3 else ASCIIUsernameValidator()    username = models.CharField(        _('username'),        max_length=150,        unique=True,        help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),        validators=[username_validator],        error_messages={            'unique': _("A user with that username already exists."),        },    )    first_name = models.CharField(_('first name'), max_length=30, blank=True)    last_name = models.CharField(_('last name'), max_length=30, blank=True)    email = models.EmailField(_('email address'), blank=True)    is_staff = models.BooleanField(        _('staff status'),        default=False,        help_text=_('Designates whether the user can log into this admin site.'),    )    is_active = models.BooleanField(        _('active'),        default=True,        help_text=_(            'Designates whether this user should be treated as active. '            'Unselect this instead of deleting accounts.'        ),    )    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)    objects = UserManager()    EMAIL_FIELD = 'email'    USERNAME_FIELD = 'username'    REQUIRED_FIELDS = ['email']    class Meta:        verbose_name = _('user')        verbose_name_plural = _('users')        abstract = True    def clean(self):        super(AbstractUser, self).clean()        self.email = self.__class__.objects.normalize_email(self.email)    def get_full_name(self):        """        Returns the first_name plus the last_name, with a space in between.        """        full_name = '%s %s' % (self.first_name, self.last_name)        return full_name.strip()    def get_short_name(self):        "Returns the short name for the user."        return self.first_name    def email_user(self, subject, message, from_email=None, **kwargs):        """        Sends an email to this User.        """        send_mail(subject, message, from_email, [self.email], **kwargs)

注: 1 权限部分参考了原文: 非常感谢!!

​ 2 后续我会提供: 注册/验证/登录/注销封装好的类,感谢大家阅读!!!

转载地址:http://nvmml.baihongyu.com/

你可能感兴趣的文章
注册表-禁用与解开注册表5种方法
查看>>
spring.net aop 讲解
查看>>
java它们的定义jar套餐读Excel(这包括2003和2007)数据,和实例
查看>>
hdu 4493 Tutor
查看>>
LR破解版录制手机脚本
查看>>
理解javascript中的策略模式
查看>>
ECLIPSE实现了界面显示所有类
查看>>
Ubuntu logomaker sh: 1: pngtopnm: not found 解决方案
查看>>
sql 子查询stuff功能(同一个人的多任务,多领域成为字符串)
查看>>
iOS8新特性(2)——UIPopoverController和UIPresentationController
查看>>
你写的Try...Catch真的有必要么?
查看>>
4安德鲁斯.2.2在系统,具有系统权限的应用程序无法读取或写入SD卡
查看>>
CSS3布局之box-flex的使用
查看>>
CentOS 7系统挂载NTFS分区的移动硬盘(转载及体验 CentOS6.5系统挂载NTFS分区的移动硬盘)...
查看>>
poj 3071 可能DP
查看>>
WPF一步步开发XMPP IM客户端1:入门
查看>>
【转】14.5.6 禁止和激活中断线
查看>>
[saiku] 将saiku自带的H2嵌入式数据库迁移到本地mysql数据库
查看>>
Java四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor...
查看>>
[转] 再探java基础——break和continue的用法
查看>>