User 模型
一, User 模型简介
1. 是验证和授权框架的核心模型, 完整路径为: django.contrib.auth.models.User
2. 模型中拥有的字段:
1. username: 用户名, max_lenght = 150, 不能为空且必须唯一, 可以包含字符: _ @ + . -, 可以包含数字和英文
2. first_name: 外国人的 first_name,max_lenght = 150, 可以为空
3. last_name: 外国人的 last_name,max_lenght = 150, 可以为空
4. email: 邮箱, 可以为空
5. password: 密码, 经过哈希加密后的密码
6. groups: 分组, 一个用户可以属于多个分组, 一个分组可以拥有多个用户
7. user_permissions: 权限
8. is_staff: 是否可以进入到 admin 站点, 代表是否为员工
9. is_active: 是否可用 True/False
10. is_superuser: 是否为超级管理员, 拥有网站所有权限
11. last_login: 上次登录时间
12. date_joined: 账号创建时间
二, User 模型基本用法 (一般会将 User 模型进行拓展重构, 那样不会生成不必要的一些字段):
1. 用户创建 (必须传递字段: username,email,password)
. 创建普通用户 (模型. objects.create_user()):
示例代码:
- from django.contrib.auth.models import User
- # 创建一个普通用户
- user = User.objects.create_user('lijingxuan','lijingxuan@qq.com','123456')
- # 对 user 对象模型中的字段进行修改
- user.last_name='jingxuan'
- user.save()
. 创建超级用户 (模型. objects.create_superuser()):
使用代码创建:
- from django.contrib.auth.models import User
- user = User.objects.create_superuser('lijingxuan','lijingxuan@qq.com','123456')
在终端通过命令行的方式创建: python manage.py createsuperuser
2. 密码修改 (对象. set_password()):
示例代码:
- from django.contrib.auth.models import User
- # 获得主键为 1 的用户数据
- user = User.objects.get(pk=1)
- # 使用 set_password() 方法将密码加密后, 存入数据库
- user.set_password('新的密码')
- user.save()
3. 登录验证 (django.contrib.auth.authenticate):
1. 这个方法只能通过: username 和 password 进行验证, 可以通过重构设置 User 模型中 USERNAME_FIELD 字段值来更改
代码示例:
- from dango.contrib.auth import authenticate
- # 如果验证失败将返回 None
- user = authenticate(username='lijingxuan',password='123456')
- # 默认 request=None, 在视图中使用时需要传入
- #user = authenticate(request,username='lijingxuan',password='123456')
- if user is not None: # 验证通过 else: # 验证失败
三, User 模型的拓展 (重点部分):
1. 方法 1: 设置 Proxy 模型
采用情况: 当对 User 模型中的字段无须进行修改, 只是在此基础上增加一些处理方法, 则可采纳
缺点: 拓展性差
示例代码:
- from django.contrib.auth import User
- # 定义一个 Person 继承自 User
- class Person(User):
- # 在 Meta 中设置 proxy 为 True, 表示这个是 User 的一个代理模型
- class Meta:
- proxy=True
- def get_blacklist(self):
- # 自定义一个方法, 返回没有被拉黑的用户账号信息
- # User.objects.all() 与 Person.objects.all() 是等价的, 因为他们都从 User 模型中获取数据
- return self.objects.filter(is_active=Flase)
2. 方法 2: 一对一外键
采用情况: 当对验证方法 authenticate 没有其他要求 (验证 username 和 password 即可完成), 但是有想要增加一些新字段, 则可采用
缺点: 拓展性一般
代码示例:
- from django.contrib.auth.models improt User
- from django.db improt models
- # receiver: 新号处理方法, 当 User 模型调用了 save 方法, 那么就会创建一个 UserExtension 对象和 User 进行绑定
- from django.dispatch import receiver
- from django.db.models.signals import post_save
- # 自动以一个模型
- class UserExtension(models.Model):
- #与 User 模型进行绑定, 当 User 调用 save() 方法的时候, 会发送一个信号, 通过 receiver 来监听 related_name: 区别名
- user = models.OneToOneField(User,on_delete=models.CASCADE,related_name='extension')
- birthday = models.DateField(null=True,blank=True)
- school = models.CharField(max_length=100)
- # 信号监听装饰器: 监听 User 模型的 save 方法, 一旦 User 模型使用 save 方法则会执行 create_user_extension 方法
- @receiver(post_save,sender=User)
- def create_user_extension(sender,instance,created,**kwargs):
- # 创建一个处理方法:
- # 参数: create: 是否为创建, instance:User 对象, sender: 发送者
- if created:
- # 如果为新创建对象, 则创建一个对应的对象
- UserExtension.objects.create(user=instance)
- else:
- # 如果为已有的对象, 则也保存一下
- instance.extension.save()
3. 继承 1: AbstractUser:
应用场景: 对用户验证 authenticate 不满意, 不想要修改 User 模型上的字段但想增加一些字段, 那么可以直接继承 django.contrib.auth.models.AbstractUser, 这个是 User 模型的父类
缺点: 会差生一些不想要的字段
代码示例:
- from django.db import models
- # from django.contrib.auth.models import User
- from django.contrib.auth.models import BaseUserManager,AbstractUser
- class UserManager(BaseUserManager):
- def _create_user(self,telephone,username,password,**kwargs):
- if not telephone:
- raise ValueError('手机号码不能为空!')
- if not password:
- raise ValueError('密码不能为空!')
- user = self.model(telephone = telephone,username=username,**kwargs)
- user.set_password(password)
- user.save()
- def create_user(self,telephone,username,password,**kwargs):
- kwargs['is_superuser'] = False
- return self._create_user(telephone,username,password,**kwargs)
- def create_superuser(self,telephone,username,password,**kwargs):
- kwargs['is_superuser'] = True
- return self._create_user(telephone,username,password,**kwargs)
- # 继承自 AbstractUser, 可以添加字段, 修改默认验证字段与 objects 的重写
- class User(AbstractUser):
- telephone = models.CharField(max_length=11,unique=True)
- school = models.CharField(max_length=100)
- #修改默认验证字段, 从 username 修改为 telephone
- USERNAME_FIELD = 'telephone'
- REQUIRED_FIELDS = []
- objects = UserManager()
继承 2: AbstractBaseUser:
应用场景: 修改默认的验证方式, 并且对原来 User 模型中的某些字段不想要, 那么可以自定义一个模型, 然后继承自 AbstractBaseUser, 再添加你想要的字段
步骤:
1> 创建模型 和 自定义用户创建方法 (Manager):
- from django.db import models
- # from django.contrib.auth.models import User
- from django.contrib.auth.models import BaseUserManager,AbstractUser
- # 自定义用户验证方法 (objects)
- class UserManager(BaseUserManager):
- def _create_user(self,telephone,username,password,**kwargs):
- if not telephone:
- raise ValueError('手机号码不能为空!')
- if not password:
- raise ValueError('密码不能为空!')
- user = self.model(telephone = telephone,username=username,**kwargs)
- user.set_password(password)
- user.save()
- def create_user(self,telephone,username,password,**kwargs):
- kwargs['is_superuser'] = False
- return self._create_user(telephone,username,password,**kwargs)
- def create_superuser(self,telephone,username,password,**kwargs):
- kwargs['is_superuser'] = True
- return self._create_user(telephone,username,password,**kwargs)
- class User(AbstractBaseUser,PermissionsMixin):
- email = models.EmailField(unique=True)
- username = models.CharField(max_length=150)
- telephone = models.CharField(max_length=11,unique=True)
- # 标识用户是否可用, 是否被拉黑
- is_active = models.BooleanField(default=True)
- # 修改默认验证字段为 telephone
- USERNAME_FIELD = 'telephone'
- # 当通过 createsuperuser 管理命令创建一个用户时的提示, 一个列表
- REQUIRED_FIELDS = []
- # 将 objects 方法执行 UserManager
- objects = UserManager()
- # 获取完整的名称
- def get_full_name(self):
- return self.username
- # 获取一个比较简短的用户名
- def get_short_name(self):
- return self.username
2. 在 settings 中配置 AUTH_USER_MODEL='app 名称. User'
3. 使用自定义模型
代码示例:
方法 1:
- from django.db import models
- from myauth.models import User
- class Article(models.Model):
- title = models.CharField(max_length=100)
- content = models.TextField()
- # 设置外键
- author = models.ForeignKey(User, on_delete=models.CASCADE)
方法 2(建议):
- from django.db import models
- from django.conf import settings
- class Article(models.Model):
- title = models.CharField(max_length=100)
- content = models.TextField()
- # 使用 settings 中定义的 AUTH_USER_MODEL 字段来表示, 为了更好的使用性
- author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
四, 权限和分组
1. 登录: django.contrib.auth.login
. 在使用 authenticate 进行验证后, 如果通过验证, 则会返回一个 user 对象, 可以使用 django.contrib.auth.login 进行登录
. 示例代码:
- def my_login(request):
- if request.method == 'GET'
- return render(request,'login.html')
- else:
- # 将 post 数据放入自定义的表单验证方法: LoginForm 中
- form = LoginForm(request.POST)
- # 判断表单数据是否验证成功
- if form.is_valid():
- # 得到表单数据
- telephone = form.cleaned_data.get('telephone')
- password = form.cleaned_data.get('password')
- remember = form.cleaned_data.get('remember')
- # 进行表单验证
- user = authenticate(request,username=username,password=password)
- # 判断是否验证成功
- if user is not None and user.is_active:
- # 判断用户是否可用
- # 进行登录: 将 user 的主键放到 request.session['pk'] 中
- login(request,user)
- if remember:
- # 判断是否需要记住我
- # 设置登录过期时间, session.set_expiry(None): 表示没有过期时间
- request.session.set_expiry(None)
- else:
- # 设置登录过期时间, session.set_expiry(0): 表示当关闭浏览器后, 就过期
- request.session.set_expiry(0)
- # 查找 next 参数内容
- next_url = request.GET.get('next')
- if next_url:# 如果找到 next 内容, 则重定向到 next 参数代表的页面
- return redirect(next_url)
- else:
- # 如果没有 next 参数, 则返回到登录成功后的首页
- return HttpResponse('登录成功')
- else:
- # 账号或密码错误
- else:
- # 表单验证失败, 登录失败, 重定向到 视图
- return redirect(reverse('视图名称'))
2. 注销: django.contrib.auth.logout
- from django.contrib.auth import logout
- def my_logout(request):
- # 就是把 session 的登录信息清除掉
- logout(request)
- return HttpResponse('成功退出登录')
3. 登录限制: django.contrib.auth.decorators.login_required
1. 通过一个装饰器进行限制:@login_required()
代码示例:
- from django.contrib.auth.decorators import login_requried
- # 装饰器: 当没有登录的情况下访问 my_view, 则会重定向到指定的 login_url, 并且会在 login_url 地址的后面加上一个 next 参数, 值为你在未登录前访问的页面, 在下次登录时可以直接重定向到 next 所代表的页面
- @login_required(login_url='/accounts/login/')
- def my_view(request):
- pass
4. 权限:
来源: http://www.bubuko.com/infodetail-2713527.html