02-内置User模型基本使用

  1. 用户对象
    1. User模型
      1. 字段:
      2. Models类
    2. User模型的基本用法
      1. 创建用户
      2. 创建超级用户
      3. 修改密码
      4. 登录验证

用户对象

User模型

User模型是这个框架的核心部分。他的完整的路径是在django.contrib.auth.models.User。以下对这个User对象做一个简单了解:

字段:

内置的User模型拥有以下的字段:

  • username:用户名。150个字符以内。可以包含数字和英文字符,以及_、@、+、.和-字符。不能为空,且必须唯一!

  • first_name:歪果仁的first_name,在30个字符以内。可以为空。

  • last_name:歪果仁的last_name,在150个字符以内。可以为空。

  • email:邮箱。可以为空。

  • password:密码。经过哈希过后的密码。

  • groups:分组。一个用户可以属于多个分组,一个分组可以拥有多个用户。groups这个字段是跟Group的一个多对多的关系。

  • user_permissions:权限。一个用户可以拥有多个权限,一个权限可以被多个用户所有用。和Permission属于一种多对多的关系。

  • is_staff:是否可以进入到admin的站点。代表是否是员工。

  • is_active:是否是可用的。对于一些想要删除账号的数据,我们设置这个值为False就可以了,而不是真正的从数据库中删除。

  • is_superuser:是否是超级管理员。如果是超级管理员,那么拥有整个网站的所有权限。

  • last_login:上次登录的时间。

  • date_joined:账号创建的时间。

Models类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
from django.contrib import auth
from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import PermissionDenied
from django.core.mail import send_mail
from django.db import models
from django.db.models.manager import EmptyManager
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

from .validators import UnicodeUsernameValidator


def update_last_login(sender, user, **kwargs):
"""
A signal receiver which updates the last_login date for
the user logging in.
"""
user.last_login = timezone.now()
user.save(update_fields=['last_login'])


class PermissionManager(models.Manager):
use_in_migrations = True

def get_by_natural_key(self, codename, app_label, model):
return self.get(
codename=codename,
content_type=ContentType.objects.db_manager(self.db).get_by_natural_key(app_label, model),
)


class 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,
models.CASCADE,
verbose_name=_('content type'),
)
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" % (
self.content_type.app_label,
self.content_type,
self.name,
)

def natural_key(self):
return (self.codename,) + self.content_type.natural_key()
natural_key.dependencies = ['contenttypes.contenttype']


class GroupManager(models.Manager):
"""
The manager for the auth's Group model.
"""
use_in_migrations = True

def get_by_natural_key(self, name):
return self.get(name=name)


class 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,)


class UserManager(BaseUserManager):
use_in_migrations = True

def _create_user(self, username, email, password, **extra_fields):
"""
Create and save a user with the given username, email, and password.
"""
if not username:
raise ValueError('The given username must be set')
email = self.normalize_email(email)
username = self.model.normalize_username(username)
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):
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(username, email, password, **extra_fields)

def create_superuser(self, username, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)

if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')

return self._create_user(username, email, password, **extra_fields)


# A few helper functions for common logic between User and AnonymousUser.
def _user_get_all_permissions(user, obj):
permissions = set()
for backend in auth.get_backends():
if hasattr(backend, "get_all_permissions"):
permissions.update(backend.get_all_permissions(user, obj))
return permissions


def _user_has_perm(user, perm, obj):
"""
A backend can raise `PermissionDenied` to short-circuit permission checking.
"""
for backend in auth.get_backends():
if not hasattr(backend, 'has_perm'):
continue
try:
if backend.has_perm(user, perm, obj):
return True
except PermissionDenied:
return False
return False


def _user_has_module_perms(user, app_label):
"""
A backend can raise `PermissionDenied` to short-circuit permission checking.
"""
for backend in auth.get_backends():
if not hasattr(backend, 'has_module_perms'):
continue
try:
if backend.has_module_perms(user, app_label):
return True
except PermissionDenied:
return False
return False


class PermissionsMixin(models.Model):
"""
Add the fields and methods necessary to support the Group and Permission
models 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 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",
)

class Meta:
abstract = True

def get_group_permissions(self, obj=None):
"""
Return a list of permission strings that this user has through their
groups. Query all available auth backends. If an object is passed in,
return only permissions matching this object.
"""
permissions = set()
for backend in auth.get_backends():
if hasattr(backend, "get_group_permissions"):
permissions.update(backend.get_group_permissions(self, obj))
return permissions

def get_all_permissions(self, obj=None):
return _user_get_all_permissions(self, obj)

def has_perm(self, perm, obj=None):
"""
Return True if the user has the specified permission. Query all
available auth backends, but return immediately if any backend returns
True. Thus, a user who has permission from a single auth backend is
assumed to have permission in general. If an object is provided, check
permissions for that object.
"""
# Active superusers have all permissions.
if self.is_active and self.is_superuser:
return True

# Otherwise we need to check the backends.
return _user_has_perm(self, perm, obj)

def has_perms(self, perm_list, obj=None):
"""
Return True if the user has each of the specified permissions. If
object is passed, check if the user has all required perms for it.
"""
return all(self.has_perm(perm, obj) for perm in perm_list)

def has_module_perms(self, app_label):
"""
Return True if the user has any permissions in the given app label.
Use simlar logic as has_perm(), above.
"""
# Active superusers have all permissions.
if self.is_active and self.is_superuser:
return True

return _user_has_module_perms(self, app_label)


class AbstractUser(AbstractBaseUser, PermissionsMixin):
"""
An abstract base class implementing a fully featured User model with
admin-compliant permissions.

Username and password are required. Other fields are optional.
"""

#用户名
username_validator = UnicodeUsernameValidator()
#设置为唯一,并且以后验证用户名和密码是否正确的时候就是用的username
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=150, 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().clean()
self.email = self.__class__.objects.normalize_email(self.email)

def get_full_name(self):
"""
Return 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):
"""Return the short name for the user."""
return self.first_name

def email_user(self, subject, message, from_email=None, **kwargs):
"""Send an email to this user."""
send_mail(subject, message, from_email, [self.email], **kwargs)


class User(AbstractUser):
"""
Users within the Django authentication system are represented by this
model.

Username, password and email are required. Other fields are optional.
"""
class Meta(AbstractUser.Meta):
swappable = 'AUTH_USER_MODEL'


class AnonymousUser:
id = None
pk = None
username = ''
is_staff = False
is_active = False
is_superuser = False
_groups = EmptyManager(Group)
_user_permissions = EmptyManager(Permission)

def __str__(self):
return 'AnonymousUser'

def __eq__(self, other):
return isinstance(other, self.__class__)

def __hash__(self):
return 1 # instances always return the same hash value

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.")

@property
def groups(self):
return self._groups

@property
def user_permissions(self):
return self._user_permissions

def get_group_permissions(self, obj=None):
return set()

def get_all_permissions(self, obj=None):
return _user_get_all_permissions(self, obj=obj)

def has_perm(self, perm, obj=None):
return _user_has_perm(self, perm, obj=obj)

def has_perms(self, perm_list, obj=None):
for perm in perm_list:
if not self.has_perm(perm, obj):
return False
return True

def has_module_perms(self, module):
return _user_has_module_perms(self, module)

@property
def is_anonymous(self):
return True

@property
def is_authenticated(self):
return False

def get_username(self):
return self.username

User模型的基本用法

创建用户

通过create_user方法可以快速的创建用户。这个方法必须要传递username、email、password。

示例代码如下:

1
2
3
4
5
from django.contrib.auth.models import User
user = User.objects.create_user('zhiliao','hynever@zhiliao.com','111111')
# 此时user对象已经存储到数据库中了。当然你还可以继续使用user对象进行一些修改
user.last_name = 'abc'
user.save()

创建超级用户

创建超级用户有两种方式。第一种是使用代码的方式。用代码创建超级用户跟创建普通用户非常的类似,只不过是使用create_superuser。示例代码如下:

1
2
from django.contrib.auth.models import User
User.objects.create_superuser('admin','admin@163.com','111111')

也可以通过命令行的方式。命令如下:

1
python manage.py createsuperuser

后面就会提示你输入用户名、邮箱以及密码。

1
2
3
4
5
6
7
#需要输入的命令
C:\Users\Administrator\Desktop\Django项目\Students_comm>python manage.py createsuperuser
Username (leave blank to use 'administrator'): #用户名
Email address: #emali 可以为空
Password: #密码:不可以纯数字,低于6位数
Password (again): #确认密码
Superuser created successfully. #提示超级用户创建成功

修改密码

因为密码是需要经过加密后才能存储进去的。所以如果想要修改密码,不能直接修改password字段,而需要通过调用set_password来达到修改密码的目的。示例代码如下:

1
2
3
4
from django.contrib.auth.models import User
user = User.objects.get(pk=1)
user.set_password('新的密码')
user.save()

登录验证

Django的验证系统已经帮我们实现了登录验证的功能。通过django.contrib.auth.authenticate即可实现。这个方法只能通过username和password来进行验证。示例代码如下:

1
2
3
4
5
6
7
from django.contrib.auth import authenticate
user = authenticate(username='zhiliao', password='111111')
# 如果验证通过了,那么就会返回一个user对象。
if user is not None:
# 执行验证通过后的代码
else:
# 执行验证没有通过的代码。

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 jaytp@qq.com
目录
主站