[Python]Django 模型

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: [Python]Django 模型

🍉 前言

系列文章目录

[Python]目录

🍉 Django 模型

Django 框架中,模型用于实现与数据库的交互,如数据的增删改查等。

在 Django 框架中,模型用于描述数据库表结构,一个模型(Model)对应一个数据表,模型中的字段对应数据表中的一个字段,一个模型对象对应数据表中的一条记录。

🍉 定义模型

所有的 Django 模型必须继承 Model 类,Model 类位于包 django.db.models 中。

🥝 语法

from django.db.models import Model
class 模型名(Model):
    字段
    其他属性或方法
    ...

🥝 常用模型字段类型

🥑 AutoField

数据库中的自动增长类型,相当于自动增长的IntegerField类型字段,对应MySQL中的int类型,可以用于ID的自动增长。

通常我们不需要设置该类型的ID字段,因为如果没有指定,django会为表创建自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后django不会再创建自动增长的主键列。

🥑 BooleanField

一个真/假(True/False)的布尔类型字段,对应MySQL中的tinyint类型。

该类型的字段如果没有设置默认值,则该字段的默认值为None。

该类型的字段默认对应CheckboxInput表单部件。

🥑 NullBooleanField

支持Null、True、False三种值。

🥑 CharField

字符类型字段,对应MySQL中的varchar类型。

该类型的字段必须设置字符的最大个数,即必须设置max_length参数。

该类型的字段默认对应TextInput表单部件。

🥑 DateField

日期字段,对应MySQL中的date类型。

该类型的字段默认对应DateInput表单部件。

对于 DateField 字段,有auto_now_add、auto_now两个参数:

1.auto_now_add:

该参数的默认值为False,如果将该参数的值设置为True,则会自动将该字段的值设置为创建时的时间,后期不能再次修改,且无法手动为该字段赋值。

该参数可以用于记录用户注册时间的字段。

2.auto_now:

该参数的默认值为False,如果将该参数的值设置为True,则会自动将该字段的值设置为当前的时间,且无法手动为该字段赋值。

该参数可以用于记录用户登录时间的字段。

注意:auto_now_add、auto_now和default选项是相互排斥的。这些选项的任何组合都会导致错误。如果将 auto_now 或 auto_now_add 设置为 True,将导致该字段设置为 editable=False(设置为不可手动编辑) 和 blank=True(不允许为空)。

🥑 DateTimeField

日期时间类型字段,对应MySQL中的datetime类型。

DateTimeField类型的字段和DateField类型的字段一样,有auto_now_add、auto_now两个参数,且用法相同。

🥑 TimeField

时间类型字段,对应MySQL中的time类型。

TimeField类型的字段和DateField类型的字段一样,有auto_now_add、auto_now两个参数,且用法相同。

🥑 IntegerField

整数类型字段,对应MySQL中的int类型。

该类型的字段的取值范围为 -2147483648 到 2147483647 ,如果取值在该范围内,则在 Django 支持的所有数据库中都是安全的。

🥑 TextField

长文本类型字段,对应MySQL中的longtext类型。

该字段的默认表单部件是一个 Textarea。该类型的字段如果指定了 max_length 属性,则 max_length 属性将会反映在自动生成的表单字段的 Textarea 部件中。

🥑 FloatField

浮点数类型字段,对应MySQL中的double类型。

FloatField 类有时会与 DecimalField 类混淆。它们都表示实数,但它们表示的方式不同。FloatField 内部使用 Python 的 float 类型,而 DecimalField 则使用 Python 的 Decimal 类型。

🥑 FileField

字符类型字段,对应MySQL中的varchar类型。

🥑 ImageField

字符类型字段,对应MySQL中的varchar类型。

🥑 DecimalField

数值型类型字段,对应MySQL中的decimal类型。

该类型字段表示固定精度的十进制。

有两个必要的参数:

1.DecimalField.max_digits:数字中允许的最大位数。注意,这个数字必须大于或等于 decimal_places。

2.DecimalField.decimal_places:与数字一起存储的小数位数。

🥝 常用字段参数

字段参数 含义
verbose_name 设置字段在admin后台管理显示的名称,如果没有指定字段名称,Django 会使用模型类中字段的属性名自动创建,并会将属性名中的下划线转换为空格。
primary_key 设置字段为主键
editable 设置该字段是否可以编辑,一般用于admin后台
max_length 设置字段的最大长度
blank 默认值为False,如果设置为True,则该字段允许为空值,该空值在数据库中表现为空字符串
null 默认值为False,如果设置为True,则该字段允许为空值,该空值在数据库中表现为null
default 设置字段的默认值
choice 设置字段的可选值,django 模型 choices 详解
db_column 设置模型对应数据表中的列名称,如果没有进行设置,则将属性名作为列名称
db_index 是否在数据库中为字段建立索引,如果是 True,将为该字段创建数据库索引
unique 是否在数据库中为字段建立唯一索引,如果设置为 True,这个字段的取值必须在整个表中保持值唯一
error_messages 自定义错误信息
validators 自定义错误验证

null是数据库范畴的概念,blank是表单验证范畴的概念

🥝 代码示例–定义模型类

导入 models 模块:

from django.db import models

🥑 UserBaseInfo

class UserBaseInfo(models.Model):
    """
    用户基本信息表
    """
    id = models.AutoField(verbose_name='编号', primary_key=True)
    username = models.CharField(verbose_name='用户名', max_length=30)
    password = models.CharField(verbose_name='密码', max_length=20)
    status = models.CharField(verbose_name='状态', max_length=1)
    # 指定在数据库表中字段的名称为createDate,且自动将该字段的值设置为创建时的时间后期不能再次修改,不能手动为该字段赋值
    createdate = models.DateTimeField(verbose_name='创建时间', db_column='createDate', auto_now_add=True)

🥑 UserExtraInfo

class UserExtraInfo(models.Model):
    """
    用户扩展信息表
    """
    id = models.AutoField(verbose_name='编号', primary_key=True)
    username = models.CharField(verbose_name='用户名', max_length=30)
    password = models.CharField(verbose_name='密码', max_length=20)
    sex = models.CharField(verbose_name='性别', max_length=1, default='male')
    salary = models.DecimalField(verbose_name='工资', max_digits=8, decimal_places=2)  # 最大位数8位,其中小数2位
    birthday = models.DateField(verbose_name='出生日期')
    age = models.IntegerField(verbose_name='年龄', default=0)
    email = models.CharField(verbose_name='邮箱', max_length=30, blank=True)  # 允许为空,为空时数据库中存储的数据为空字符串
    status = models.CharField(verbose_name='状态', max_length=1)
    createdate = models.DateTimeField(verbose_name='创建时间', db_column='createDate', auto_now_add=True)

🥑 DepartInfo

class DepartInfo(models.Model):
    """
    部门信息表
    """
    id = models.AutoField(verbose_name='编号', primary_key=True)
    departname = models.CharField(verbose_name='部门名称', max_length=20)
    createdate = models.DateTimeField(verbose_name='创建时间', db_column='createDate', auto_now_add=True)

🥑 SkillInfo

class SkillInfo(models.Model):
  """
    员工技能表
    """
    id = models.AutoField(verbose_name='编号', primary_key=True)
    skillname = models.CharField(verbose_name='技能名称', db_column='skillName', max_length=20)
    createdate = models.DateTimeField(verbose_name='创建时间', db_column='createDate', auto_now_add=True)

🥝 __str__()方法

__str__()方法用于设置输出模型对象时的返回值,默认的返回值为模型对象,可以通过__str__()方法设置打印模型对象的返回值。

注意__str__()方法只允许返回字符类型的字段,如果要返回其他类型的字段,需要使用str()函数将字段的值转换为字符类型。

🥑 代码示例

class UserBaseInfo(models.Model):
    """
    用户基本信息表
    """
    ......
    def __str__(self):
        # 由于`__str__()`方法只允许返回字符类型的字段,所以对于整数类型的id字段需要使用str()函数将字段的值转换为字符类型
        return str(self.id) + ': ' + '用户名-' + self.username + '\t用户状态-' + self.status
class UserExtraInfo(models.Model):
    """
    用户扩展信息表
    """
    ......
    def __str__(self):
        return str(self.id) + ': ' + '用户名-' + self.username + '\t用户状态-' + self.status
class DepartInfo(models.Model):
    """
    部门信息表
    """
    ......
    def __str__(self):
        return str(self.id) + ': ' + '部门名称-' + self.departname
class SkillInfo(models.Model):
  """
    员工技能表
    """
    ......
    def __str__(self):
        return str(self.id) + ': ' + '技能名称-' + self.departname

测试:

from subapp01.models import UserBaseInfo, UserExtraInfo, DepartInfo, SkillInfo  # 导入模型类型
from django.http import HttpResponse  # 导入返回响应的类
# Create your views here.
def fun(request):
    users = UserBaseInfo.objects.all()  # 获取userbaseinfo表中的所有记录
    for user in users:  # 循环遍历打印userbaseinfo表中的所有用户信息记录对象
        print(user)  # str(self.id) + ': ' + '用户名-' + self.username + '\t用户状态-' + self.status
    return HttpResponse(users)  # 向客户端返回响应

🥝 Meta 类

Django 模型中的 Meta 类是一个内部类,用于定义一些 Django 模型的行为特性。

Meta 类的常用参数:

参数 含义
abstract 如果将该参数的值设置为True,则该模型类为抽象类
db_table 设置该模型对象的数据表的名称,如果没有设置该参数,则默认的数据表名称为“应用名+下划线+模型类名”
ordering 模型对象返回的记录结果集按照哪个字段进行排序。按照字段升序排列:ordering=[“字段名”];按照字段降序排列:ordering=[“-字段名”];按照多个字段进行排序:ordering=[“字段名1”, “字段名2”, …]
verbose_name 设置模型类在后台管理中显示的名称
index_together 设置数据库中表的联合索引
unique_together 设置数据库中表的联合唯一索引

🥑 代码示例

class UserBaseInfo(models.Model):
    """
    用户基本信息表
    """
    ......
    def __str__(self):
        ......
    class Meta:
        db_table = 'user_base_info'  # 在数据库中该模型对应的表的名称
        verbose_name = '用户基本信息表'  # 模型类在后台管理中显示的名称

🍉 模型的关系

数据库中的表存在一对一、一对多、多对多的关联关系,Django中的模型对应数据库中的表,所以,Django中的模型也存在一对一、一对多、多对多的关联关系。

🥝 一对一

建立Django模型之间一对一的关联关系,在模型中使用models模块下OneToOneField()方法来构建模型的一对一关联关系。

使用OneToOneField()方法来构建模型间的一对一关联关系,相当于在模型中创建了一个引用另一个模型指定字段的外键。

哪个数据表需要外键,就把OneToOneField()方法放到该数据表对应的模型中。

models模块下OneToOneField()方法的参数:

参数 含义
to 要进行关联的模型名称
to_field 要进行关联的模型中的字段名称
on_delete 指定在删除关联模型(被引用)中的数据时,对本模型中的数据如何进行处理

on_delete参数的配置选项:

配置选项 含义
CASCADE 在删除关联模型(被引用)中的数据时,如果外键所在的模型(引用)一并删除有关联的数据,即级联删除
PROTECT 在删除关联模型(被引用)中的数据时,采用保护机制抛出错误,不删除外键所在模型(引用)的相关数据,即阻止删除操作
SET_NULL 在删除关联模型(被引用)中的数据时,对于外键所在的模型(引用)如果外键字段null=True,则将外键所在模型(引用)的外键字段的相关数据设置为null
SET_DEFAULT 在删除关联模型(被引用)中的数据时,对于外键所在的模型(引用)如果外键字段有设置默认值,则将外键所在模型(引用)的外键字段的相关数据设置为默认值
SET 在删除关联模型(被引用)中的数据时,将外键所在模型(引用)的外键字段的相关数据设置为指定的值
DO_NOTHING 在删除关联模型(被引用)中的数据时,对于外键所在的模型(引用)不做任何操作

🥑 代码示例

用户基本信息表UserBaseInfo和用户扩展信息表UserExtraInfo之间的关系为一对一的关系,由于在用户基本信息表中需要建立外键关联用户扩展信息表中的数据记录,所以在用户基本信息表对应的模型中使用OneToOneField()方法建立外键关联用户扩展信息表的数据记录。

class UserExtraInfo(models.Model):
  """
    用户扩展信息表
    """
    ......
class UserBaseInfo(models.Model):
    """
    用户基本信息表
    """
    ......
    # 设置外键,关联用户扩展信息表,且用户扩展信息表数据删除时进行级联操作删除基本信息表的信息,该字段允许为空
    # 自动关联用户扩展信息表的主键
    user = models.OneToOneField(to=UserExtraInfo, on_delete=models.CASCADE, null=True)
    def __str__(self):
        ......
    class Meta:
        ......

🥝 一对多

建立Django模型之间一对多的关联关系,在模型中使用models模块下ForeignKey()方法来构建模型间的一对多关联关系。

通常把ForeignKey()方法放到“多”的数据表对应的模型中,即在“多”对应的模型中建立引用“一”对应的模型中字段数据的外键。

ForeignKey()方法的参数:

参数 含义
to 要进行关联的模型名称
to_field 要进行关联的模型中的字段名称
on_delete 指定在删除关联模型(被引用)中的数据时,对本模型中的数据如何进行处理,在ForeignKey()方法中的on_delete的配置选项与OneToOneField()方法中的on_delete的配置选项一致
related_name 默认值为None,指定在反向操作时访问“多”对应模型使用的字段名,即通过“一”对应的模型查询“多”对应的模型中的相关数据时使用的字段名(外键定义在“多”对应的模型中),如果没有指定,则反向操作时使用的字段名为“表名_set”
related_query_name 默认值为None,在反向操作时访问“多”对应模型中某个字段使用的名字,如果没有指定,则反向操作时使用的名字为“表名_字段名”,只能指定前缀,即“表名”
db_constraint 是否在数据库中创建外键约束,设置为True,在数据库中创建外键约束

🥑 代码示例

用户扩展信息表UserExtraInfo和部门信息表DepartInfo之间的关系为多对一的关系,由于在用户扩展信息表中需要建立外键关联部门信息表,所以在用户扩展信息表对应的模型中使用ForeignKey()方法建立外键关联部门信息表。

class DepartInfo(models.Model):
    """
    部门信息表
    """
    ......
class UserExtraInfo(models.Model):
    """
    用户扩展信息表
    """
    ......
    depart = models.ForeignKey(
        to=DepartInfo,  # 关联的模型为部门信息模型DepartInfo
        null=True,  # 该字段允许为空
        on_delete=models.SET_NULL,  # 当部门信息表的记录删除时将该表的相关数据的相关字段设置为null
        related_name='user_extra_info',  # 当进行反向操作时,使用user_extra_info代表该模型
        db_constraint=True  # 在数据库中建立外键约束
    )
    def __str__(self):
        ......

🥝 多对多

建立Django模型之间多对多的关联关系,在模型中使用models模块下ManyToManyField()方法来构建模型间的多对多关联关系。

对于使用ManyToManyField()方法建立模型之间的多对多关系,该方法放在哪个模型并没有什么区别,因为通过ManyToManyField()方法建立模型之间的多对多关系,会在数据库中生成一个关联两个模型对应的数据表的第三张表。

ManyToManyField()方法的参数:

参数 含义
to 要进行关联的模型名称
db_constraint 是否在数据库中创建外键约束,设置为True,在数据库中创建外键约束
db_table 默认值为None,指定关联两个模型对应表的第三张表的表名,如果不指定则第三张表表名默认为“模型名称1_模型名称2”

🥑 代码示例

用户扩展信息表UserExtraInfo和用户技能表SkillInfo之间的关系为多对多的关系,使用ManyToManyField()方法建立两个模型之间的多对多关联。

class SkillInfo(models.Model):
    """
    用户技能表
    """
    ......
class UserExtraInfo(models.Model):
    """
    用户扩展信息表
    """
    ......
    # 建立该模型与用户技能模型之间的多对多关联关系,在数据库中创建外键约束,用于关联两个模型对应表的第三表的表名为user_skill
    skill = models.ManyToManyField(to=SkillInfo, db_constraint=True, db_table='user_skill')
    def __str__(self):
        ......

🍉 迁移数据在数据库生成表

🥝 生成迁移文件

在迁移数据之前,首先要生成迁移文件。

生成所有子应用迁移文件的命令:

python manage.py makemigrations

在此之前已有进行数据迁移,所以在这迁移的为修改后的内容

🥝 执行迁移

执行迁移,在数据库中创建对应的表,将数据同步到数据库中。

在第一次进行迁移时,数据库中不能存在同名的数据表,否则会迁移失败

执行迁移的命令:

python manage.py migrate

🥝 之前迁移过程截图

生成迁移文件

python manage.py makemigrations

如果报错:

No changes detected

原因:可能子应用没有进行注册

数据迁移同步到数据库中

python manage.py migrate

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
19天前
|
机器学习/深度学习 数据采集 TensorFlow
使用Python实现智能食品消费模式分析的深度学习模型
使用Python实现智能食品消费模式分析的深度学习模型
112 70
|
26天前
|
机器学习/深度学习 数据采集 供应链
使用Python实现智能食品库存管理的深度学习模型
使用Python实现智能食品库存管理的深度学习模型
143 63
|
27天前
|
机器学习/深度学习 Python
堆叠集成策略的原理、实现方法及Python应用。堆叠通过多层模型组合,先用不同基础模型生成预测,再用元学习器整合这些预测,提升模型性能
本文深入探讨了堆叠集成策略的原理、实现方法及Python应用。堆叠通过多层模型组合,先用不同基础模型生成预测,再用元学习器整合这些预测,提升模型性能。文章详细介绍了堆叠的实现步骤,包括数据准备、基础模型训练、新训练集构建及元学习器训练,并讨论了其优缺点。
44 3
|
27天前
|
机器学习/深度学习 算法 数据挖掘
线性回归模型的原理、实现及应用,特别是在 Python 中的实践
本文深入探讨了线性回归模型的原理、实现及应用,特别是在 Python 中的实践。线性回归假设因变量与自变量间存在线性关系,通过建立线性方程预测未知数据。文章介绍了模型的基本原理、实现步骤、Python 常用库(如 Scikit-learn 和 Statsmodels)、参数解释、优缺点及扩展应用,强调了其在数据分析中的重要性和局限性。
57 3
|
8天前
|
机器学习/深度学习 数据可视化 TensorFlow
使用Python实现深度学习模型的分布式训练
使用Python实现深度学习模型的分布式训练
121 73
|
21天前
|
机器学习/深度学习 数据采集 TensorFlow
使用Python实现智能食品消费习惯分析的深度学习模型
使用Python实现智能食品消费习惯分析的深度学习模型
125 68
|
17天前
|
机器学习/深度学习 数据采集 数据挖掘
使用Python实现智能食品消费市场分析的深度学习模型
使用Python实现智能食品消费市场分析的深度学习模型
94 36
|
11天前
|
机器学习/深度学习 数据采集 供应链
使用Python实现智能食品消费需求分析的深度学习模型
使用Python实现智能食品消费需求分析的深度学习模型
55 21
|
13天前
|
机器学习/深度学习 数据采集 搜索推荐
使用Python实现智能食品消费偏好预测的深度学习模型
使用Python实现智能食品消费偏好预测的深度学习模型
56 23
|
14天前
|
机器学习/深度学习 数据采集 数据挖掘
使用Python实现智能食品消费习惯预测的深度学习模型
使用Python实现智能食品消费习惯预测的深度学习模型
65 19