django/contrib/auth/models.py
from django.contrib.auth.models import User
在《Django auth应用模块》中我们提到过 auth_user 表,在执行完毕 migrate 后,它的表结构如下所示:+--------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | password | varchar(128) | NO | | NULL | | | last_login | datetime(6) | YES | | NULL | | | is_superuser | tinyint(1) | NO | | NULL | | | username | varchar(150) | NO | UNI | NULL | | | first_name | varchar(30) | NO | | NULL | | | last_name | varchar(150) | NO | | NULL | | | email | varchar(254) | NO | | NULL | | | is_staff | tinyint(1) | NO | | NULL | | | is_active | tinyint(1) | NO | | NULL | | | date_joined | datetime(6) | NO | | NULL | | +--------------+--------------+------+-----+---------+----------------+ 11 rows in set (0.02 sec)对于上表前面介绍是我们只是一笔带过,在这里有必讲解一下需要重点理解的属性。如下所示:
class PermissionsMixin(models.Model): group=models.ManyToManyField(Group,...) user_permission=models.ManyToManyField(Permission,...)User 关联表,即 auth_user_groups 和 auth_user_user_permissions,其表分别结构如下图所示:
mysql> desc auth_user_groups; +----------+---------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+---------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | user_id | int(11) | NO | MUL | NULL | | | group_id | int(11) | NO | MUL | NULL | | +----------+---------+------+-----+---------+----------------+ 3 rows in set (0.02 sec) mysql> desc auth_user_user_permissions; +---------------+---------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------------+---------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | user_id | int(11) | NO | MUL | NULL | | | permission_id | int(11) | NO | MUL | NULL | | +---------------+---------+------+-----+---------+----------------+ 3 rows in set (0.02 sec)
class UserManager(BaseUserManager): use_in_migrations = True def _create_user(self, username, email, password, **extra_fields): """ 创建并保存具有给定用户名、电子邮件和密码的用户。 """ if not username: raise ValueError('The given username must be set') email = self.normalize_email(email) #使用户名规范化调用normalize_username username = self.model.normalize_username(username) #新建user实例 user = self.model(username=username, email=email, **extra_fields) #设置密码的方法 user.set_password(password) user.save(using=self._db) return user def create_user(self, username, email=None, password=None, **extra_fields): #普通用户的is_staff和is_superuser都为False extra_fields.setdefault('is_staff', False) extra_fields.setdefault('is_superuser', False) return self._create_user(username, email, password, **extra_fields)使用该方法的实例如下所示:
from django.contrib.auth.models import User user=User.objects.create_user('bookstore','123@163.com','python_django')同样我们可以 set_password() 方法修改密码,最后记得调用 save() 方法保存即可。
class AnonymousUser: id = None pk = None username = '' is_staff = False is_active = False is_superuser = False _groups = EmptyManager(Group) _user_permissions = EmptyManager(Permission)从源码分析可以看出 AnonymousUser 定义匿名用户的主要属性, 可以看到它的 is_staff 和 is_active 以及 is_superuser 都设置成为了 False,它还定义了一些方法如下所示:
def save(self): raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.") def delete(self): raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.") def set_password(self, raw_password): raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.") def check_password(self, raw_password): raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")从上述代码可以看出 AnonymousUser 匿名用户定义的方法都抛出了 NotImplementedError 异常,所以它并没实现任何方法。
class Group(models.Model): name = models.CharField(_('name'), max_length=150, 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,)从源码解析来看,Group 用户组之定义了一个字段 name,代表用户组的名称而且必须具有唯一性,其最大字符长度为 150,它还定义与 Permission 模型之间多对多关联关系,那么它们之间就有有一张中间表即 auth_group_permissions,通过数据库查看一下它的表结构,如下所示:
mysql> desc auth_group_permissions; +---------------+---------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------------+---------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | group_id | int(11) | NO | MUL | NULL | | | permission_id | int(11) | NO | MUL | NULL | | +---------------+---------+------+-----+---------+----------------+
In [1]: from django.contrib.auth.models import User,Group In [2]: group=Group.objects.create(name="reader") In [3]: user=User.objects.get(username="bookstore") In [4]: user.groups.add(group) In [5]: user.groups.all() Out[5]: <QuerySet [<Group: reader>]>通过上述的代码就将用户 user 加入到了组 reader 中,我们可以通过用户组权限再给这个组设置相应的权限,查看 auth_user_groups 表可得如下结果:
mysql> select * from auth_user_groups; +----+---------+----------+ | id | user_id | group_id | +----+---------+----------+ | 1 | 2 | 1 | +----+---------+----------+本节我们详细介绍了 Django 用户认证系统中的用户与用户组,从源码的角度出发对它们之间的关联关系进行了深度的剖析,通过本节的讲解大家对用户与用户组的概念不在感到陌生,在下一节我们将讲解如何进行用户的身份认证。
Copyright © 广州京杭网络科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州京杭网络科技有限公司 版权所有