侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

对Django中内置的User模型实例详解

框架(架构)  /  管理员 发布于 7年前   169

User模型

User模型是这个框架的核心部分。他的完整的路径是在django.contrib.auth.models.User。

字段

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

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

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

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

4、email:邮箱。可以为空。

5、password:密码。经过哈希过后的密码。

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

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

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

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

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

11、last_login:上次登录的时间。

12、date_joined:账号创建的时间。

User模型的基本用法:

首先我们先执行makegrations和migrate对模型进行映射。

创建用户:

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

from django.http import HttpResponsefrom django.contrib.auth.models import Userdef index(request):  user = User.objects.create_user(username='xujin',email='[email protected]',password='111111')  return HttpResponse('success')

然后我们执行上面的视图,然后进入数据库,找到auth_user这张表,我们就能查看到我们刚才创建的用户的信息了

上面的三个参数是必须传的参数,其他的参数是可选参数。我们可以在数据库中看到我们设置的密码仿佛是一窜乱码,其实这并不是乱码,而是因为我们设置的user的密码时经过哈希加密处理的,所以看起来是一窜乱码。

我们还可以对user对象进行更改数据。

def index(request):  # user = User.objects.create_user(username='xujin',email='[email protected]',password='111111')  user = User.objects.get(username='xujin')  user.last_name = 'aaa'  user.save() #更改完数据之后一定要记得保存  return HttpResponse('success')

但是对于密码这个字段,我们不能这样修改,因为这样修改的密码在数据库中是明文显示的,不会经过哈希加密处理的。我们需要使用到user的一个方法来对密码进行更改。

def index(request):  # user = User.objects.create_user(username='xujin',email='[email protected]',password='111111')  user = User.objects.get(username='xujin')  # user.last_name = 'aaa'  # user.save() #更改完数据之后一定要记得保存  # user.password = '222222' # 这样修改是错误的,在数据库中会明文显示,不会被加密处理  user.set_password('222222') # 这个方法设置的密码才会经过加密处理然后存放到数据库中去  user.save()  return HttpResponse('success')

创建超级用户:

创建超级用户有两种方式。

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

def index(request):  user = User.objects.create_superuser(username='xujin1',email='[email protected]',password='111111')  return HttpResponse('success')

这样我们就成功的创建了一个超级用户,我们也可以在数据库中的auth_user表中的is_superuser字段中查看到值为1,即时超级用户,而刚才我们创建的普通用户值就为0。

第二种创建超级用户的方式是使用命令行:

在终端输入:

python manage.py createsuperuser

这样,我们也能创建一个超级用户,但是这样对输入的密码要求比较高,不能设置很简单的密码。

注意: 因为django内置的user模型规定的是username为唯一字段,所以我们创建用户的时候username是不能重复的。

登录验证

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

from django.contrib.auth import authenticatedef index(request):  username = 'xujin'  password = '222222'  user = authenticate(request,username=username,password=password) # 验证成功之后就会返回这个user对象  if user:    print('登录成功:%s' % user.username)  else:    print('用户名或密码错误!')  return HttpResponse('success')

扩展用户模型

Django内置的User模型虽然已经足够强大了。但是有时候还是不能满足我们的需求。比如在验证用户登录的时候,他用的是用户名作为验证,而我们有时候需要通过手机号码或者邮箱来进行验证。还有比如我们想要增加一些新的字段。那么这时候我们就需要扩展用户模型了。扩展用户模型有多种方式。

1. 设置Proxy(代理)模型:

如果你对Django提供的字段,以及验证的方法都比较满意,没有什么需要改的。但是只是需要在他原有的基础之上增加一些操作的方法。那么建议使用这种方式。示例代码如下:

在models.py中创建一个代理模型:

from django.contrib.auth.models import Userclass Person(User):  class Meta:    proxy = True # 表明这是一个代理模型  @classmethod  def get_user_number(cls):    # 获取user的个数    return cls.objects.all().count()

然后在views.py导入并使用:

from .models import Persondef proxyView(request):  user_number = Person.get_user_number()  print(user_number)      # 因为我们使用了代理模型,那么以下两种写法是等价的  # User.objects.all()  # Person.objects.all()     return HttpResponse('success')

这就是代理模型的基本使用了,我们可以定义一些自己的方法,而又不需要改变原来的User模型中的方法。

因为这是一个代理的模型,所以我们不能在里面添加新的字段了,例如,我想要在Person模型中添加一个新的字段,那么就会报错,报错的大概意思就是代理模型不能添加字段。

class Person(User):  telephone = models.CharField(max_length=11)  class Meta:    proxy = True # 表明这是一个代理模型  @classmethod  def get_user_number(cls):    # 获取user的个数    return cls.objects.all().count()

执行makegrations后的报错信息为:

ERRORS:?: (models.E017) Proxy model 'Person' contains model fields.

虽然代理模型不能拥有新的字段,但是可以拥有自己的属性的。

那么如果我们想给user模型增加新的字段,那么我们可以采用另外一种方式扩展:一对一外键

一对一外键

如果你对用户验证方法authenticate没有其他要求,就是使用username和password即可完成。但是想要在原来模型的基础之上添加新的字段,那么可以使用一对一外键的方式。

首先在models.py中新建一个模型,然后使用一对一外键和User连接起来:

class UserExtension(models.Model):  # 定义一个一对一的外键  user = models.OneToOneField(User,on_delete=models.CASCADE,related_name='extension')  telephone = models.CharField(max_length=11)  school = models.CharField(max_length=100)from django.dispatch import receiverfrom django.db.models.signals import post_save# 这是一个信号函数,即每创建一个User对象时,就会新建一个userextionsion进行绑定,使用了receiver这个装饰器@receiver(post_save,sender=User)def handler_user_extension(sender,instance,created,**kwargs):  if created: # 如果是第一次创建user对象,就创建一个userextension对象进行绑定    UserExtension.objects.create(user=instance)  else: # 如果是修改user对象,那么也要将extension进行保存    instance.extension.save()

然后我们需要将我们添加的字段映射到数据库中去,执行makegrations和migrate。

然后在views.py中写入视图:

def oneView(request):  user = User.objects.create_user(username='aaaaaa',email='[email protected]',password='111111')  return HttpResponse('一对一扩展User')

添加映射,执行代码,然后就能在数据库中看到我么添加的信息了。

因为我么定义一个extention的扩展模型,那么我们就不能使用自带的authenticate来验证登录了,那么我们就可以自定义一个我们自己的authenticate来验证登录。

def my_authenticate(telephone,password):  user = User.objects.filter(extension__telephone=telephone).first()  if user:    is_correct = user.check_password(password)    if is_correct:      return user    else:      print('密码错误!')      return None  else:    print('没有找到此用户')    return Nonedef oneView(request):  # 创建一条测试数据  user = User.objects.create_user(username='bbb',email='[email protected]',password='111111')  user.extension.telephone = '18888888888'  user.save()  return HttpResponse('一对一扩展User')

上面的代码中我们定义好了一个我么自己的authenticate方法my_authenticate来验证登录,然后我么 在视图oneView中新建了一个测试数据,这个时候我们还没有使用到我们自己定义的方位,因为我们首先的新建测试数据才能使用。

运行了上面的代码之后,我们就可以使用我们自己定义的方法来验证登录了。

修改视图:

def oneView(request):  # 创建一条测试数据  # user = User.objects.create_user(username='bbb',email='[email protected]',password='111111')  # user.extension.telephone = '18888888888'  # user.save()  telephone = '18888888888'  password = '111111'  user = my_authenticate(telephone,password)  if user:    print('登录成功')  else:    print('登录失败')  return HttpResponse('一对一扩展User')

上面就是使用一对一的方式来扩展User模型。

继承自AbstractUser

对于authenticate不满意,并且不想要修改原来User对象上的一些字段,但是想要增加一些字段,那么这时候可以直接继承自django.contrib.auth.models.AbstractUser,其实这个类也是django.contrib.auth.models.User的父类。比如我们想要在原来User模型的基础之上添加一个telephone和school字段,那么示例代码如下。

首先我们先将以前所有的代码注释掉,然后在models.py中写入代码:

from django.contrib.auth.models import AbstractUser,BaseUserManager# 自定义管理工具class UserManage(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()    return user # 创建普通用户  def create_user(self,telephone,username,password,**kwargs):    kwargs['is_superuser'] = False    return self._create_user(telephone=telephone,username=username,password=password,**kwargs)  # 创建超级用户  def create_superuser(self,telephone,username,password,**kwargs):    kwargs['is_superuser'] = True    return self._create_user(telephone=telephone, username=username, password=password, **kwargs)class User(AbstractUser):  telephone = models.CharField(max_length=11,unique=True)  school = models.CharField(max_length=100)  # 我们在使用authenticate的时候,默认传入的就好似username和password字段  # 现在我们设置了这个属性的值,那么再使用authenticate的时候,就会使用我们设定的字段  USERNAME_FIELD = 'telephone'  objects = UserManage()

然后我们需要去settings中添加一个变量,来告诉Django我们修改了内置的User模型,使用的是我们自己的User模型:

AUTH_USER_MODEL = 'front.User'

上面的变量的名字不是随便取的,是必须为这个名字。

里面的值是我们定义的User模型的位置:app名.模型名。

要使用我们定义的模型,我们首先得映射到数据库中去,但是因为我们改变了内置的User的结构,并且数据库中已经移植了以前没有改变的User模型,我们现在再直接移植肯定是会报错的,那么我们就需要将所有的表进行删除,然后将迁移文件也进行删除了,才可以进行移植。才能执行makegrations和migrate命令不会报错。

然后我们在views.py中添加视图:

from .models import Userdef inherit_view(request):  telephone = '18888888888'  password = '111111'  username = 'xujin'  user = User.objects.create_user(telephone=telephone,password=password,username=username)  print(user.username)  return HttpResponse('success')

然后执行上面的代码,就能够成功的创建用户了,并且使用的使我们自定义的User模型。

那么如果我们现在需要使用authenticate来验证输入信息,我们应该验证哪一个字段呢?

def inherit_view(request):  telephone = '18888888888'  password = '111111'  username = 'xujin'  # user = User.objects.create_user(telephone=telephone,password=password,username=username)  # print(user.username)  user = authenticate(request,username=telephone,password=password)  if user:    print('登录成功')    print(user.username)  else:    print('验证失败')  return HttpResponse('success')

为什么在authenticate中,username参数我们传入的是telephone字段呢。是因为在User模型中,我们重写了USERNAME_FIELD属性,而这个属性接收的值就是authenticate中username对应的字段,因为我们在User中将USERNAME_FIELD的值改为了telephone字段,所以我们使用的时候也需要使用telephone字段,相当于username并不是表示username字段,而是我们USERNAME_FIELD属性定义的字段。

注意: USERNAME_FIELD属性值对应的字段必须设置唯一,即需要设置unique=True这个参数。

以上这篇对Django中内置的User模型实例详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


  • 上一条:
    django 通过url实现简单的权限控制的例子
    下一条:
    对Django中的权限和分组管理实例讲解
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Filament v3.1版本发布(0个评论)
    • docker + gitea搭建一个git服务器流程步骤(0个评论)
    • websocket的三种架构方式使用优缺点浅析(0个评论)
    • ubuntu20.4系统中宿主机安装nginx服务,docker容器中安装php8.2实现运行laravel10框架网站(0个评论)
    • phpstudy_pro(小皮面板)中安装最新php8.2.9版本流程步骤(0个评论)
    • 近期文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2018-05
    • 2020-02
    • 2020-03
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-11
    • 2021-03
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-08
    • 2023-08
    • 2023-10
    • 2023-12
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客