模型
-
Django 模型是描述数据的,它包含存储数据的重要字段和行为。 一个模型映射一张数据库表。
-
模型采用ORM来映射数据库表。
- 每个模型都是一个 Python 的类,这些类继承
django.db.models.Model
- 模型类的每个属性都相当于一个数据库的字段
- 利用模型访问数据库进行查询
-
如果模型中未定义主键,则表(模型)会字段添加一个
id
自增字段;如果显式地设置了primary_key,将不会自动在表(模型)中添加 id 列 -
要使模型映射到数据库表需要运行
py manage.py migrate
, 与此同时,可以py manage.py makemigrations
命令进行迁移成文件,方便以后检查、调用、重做等等 -
如果定义了模型且要使用它,需要在
setting.py
中的INSTALLED_APPS
添加由manage.py startapp
创建的app名称
字段(Field)
字段类型
字段 | 类型 |
---|---|
AutoField | 自动递增 |
BigAutoField | 64位AutoField |
BigIntegerField | 64位整数IntegerField |
BinaryField | 二进制数据 |
BooleanField | 布尔值 |
CharField | 字符串 |
DateField | 日期 |
DateTimeField | 日期和时间 |
DecimalField | 固定精度的十进制数字 |
DurationField | 存储时间段 |
EmailField | 电子邮件地址 |
FileField | 文件 |
FilePathField | 文件路径 |
FloatField | 浮点数 |
ImageField | 图像 |
IntegerField | 整数 |
GenericIPAddressField | 字符串格式的IPv4或IPv6地址 |
NullBooleanField | null(null=True) |
PositiveIntegerField | 正整数 |
PositiveSmallIntegerField | 正短整数或0 |
SlugField | 仅包含字母,数字,下划线或连字符, 用于URL |
SmallAutoField | 小整数AutoField |
SmallIntegerField | 小整数IntegerField |
TextField | 文本类型 |
TimeField | 时间 |
URLField | URL |
UUIDField | 用于存储通用唯一标识符 |
ForeignKey | 多对一的关系 (关联关系字段) |
ManyToManyField | 多对多关系 (关联关系字段) |
OneToOneField | 一对一关系 (关联关系字段) |
字段选项
选项 | 功能 |
---|---|
max_length | 指定数据库存储数据时用的字节数 |
null | 字段为空时,将数据库中该字段设置为 NULL。默认为 False |
blank | 字段允许为空。默认为 False |
choices | 将二元组用作此字段的选项; 每个二元组的第一个值会储存在数据库中,而第二个值将只会用于在表单中显示 |
db_column | 字段的数据库列的名称 |
db_index | 为字段创建数据库索引 |
db_tablespace | 如果字段已建立索引,则用于该字段的索引的数据库表空间的名称 |
default | 字段的默认值 |
editable | 字段是否可编辑 |
error_messages | 字段错误时引发的提示,值是一个字典 |
help_text | 额外的“帮助”文本 |
primary_key | 字段设置为该模型的主键 |
unique | 字段的值必须在整个表中保持唯一 |
unique_for_date | 日期字段或日期时间字段的值唯一 |
unique_for_month | 日期字段或日期时间字段中的月份的值唯一 |
unique_for_year | 日期字段或日期时间字段中的年份的值唯一 |
verbose_name | 该字段的可读名称 |
through | 指定多对多关系使用哪个中间模型 (ManyToManyField)如果中间模型有多个外键需要使用 through_fields 手动选择一个外键 |
字段属性
属性 | 功能 |
---|---|
auto_created | 是否自动创建该字段 |
concrete | 是否具有与其关联的数据库列 |
hidden | 是否使用一个字段来支持另一个非隐藏字段的功能 |
is_relation | 是否包含一个或多个其他模型的功能 |
model | 返回定义字段的模型 |
👇关系字段属性👇 | |
many_to_many | 该字段是否具有多对多关系 |
many_to_one | 该字段是否具有多对一关系 |
one_to_many | 字段是否具有一对多关系 |
one_to_one | 字段是否具有一对一关系 |
related_model | 指向与该领域相关的模型 |
字段命名限制
错误命名 | 解释 |
---|---|
Python保留字 | Python语法错误 |
字段名包含连续的多个下划线(两个及两个以上) | Django查询语法中使用双下划线提供其他功能 |
下划线结尾 | Django查询语法中使用双下划线提供其他功能 |
模型API名称如 Save、from_db、refresh_from_db、get_deferred_fields、clean_fields、clean、validate_unique、full_clean、clean_fields、update、pk、delete等 | 与模型 API 名称冲突 |
跨文件模型
模型的关系可以使用非本文件内的模型进行关联,只需import需要被关联的模型即可
官方示例:
from django.db import models
from geography.models import ZipCode
class Restaurant(models.Model):
# ...
zip_code = models.ForeignKey(
ZipCode,
on_delete=models.SET_NULL,
blank=True,
null=True,
)
Meta
使用内部 Meta类 来给模型赋予元数据(元数据:所有不是字段的东西)
Meta选项
属性 | 功能 |
---|---|
👇可用Meta选项👇 | |
abstract | 设置抽象模型 |
app_label | 如果模型是在INSTALLED_APPS中的应用程序之外定义的,它必须声明它属于哪个应用程序 |
base_manager_name | 管理者的属性名称 |
db_table | 数据库表名 |
db_tablespace | 模型的数据库表空间的名称 |
default_manager_name | 用于模型的_default_manager的管理器的名称 |
default_related_name | 从相关对象到该对象的关系使用的名称 |
get_latest_by | 模型中的字段名称或字段名称列表,这指定了要在模型管理器的Latest()和earlyest()方法中使用的默认字段。 |
managed | 默认值为True,表示Django将在migrate迁移过程中或迁移过程中创建适当的数据库表,并将其作为flush管理命令的一部分删除。如果为False,则不会对此模型执行数据库表创建或删除操作。 |
order_with_respect_to | 给定字段可排序(通常为ForeignKey) |
ordering | 默认排序 |
permissions | 创建此对象时可进入权限表的额外权限 |
default_permissions | 默认权限 |
proxy | 代理 |
required_db_features | 当前连接应具有的数据库功能列表,以便在迁移阶段考虑模型 |
required_db_vendor | 该模型特定于的受支持数据库供应商的名称 |
select_on_save | 通常不需要设置此属性。默认值为 False |
indexes | 索引 |
unique_together | unique共存 |
index_together | index共存 |
constraints | 定义约束 |
verbose_name | 对象的易读名称 |
verbose_name_plural | 对象的复数名称 |
👇只读Meta属性👇 | |
label | 对象的表示,返回app_label.object_name |
label_lower | 模型的表示,返回app_label.model_name |
模型属性
模型当中最重要的属性是 Manager
。 它是 Django 模型和数据库查询操作之间的接口,并且它被用作从数据库当中获取实例,如果没有指定自定义的 Manager
默认名称是 objects
。Manager
只能通过模型类来访问,不能通过模型实例来访问
模型方法
在模型中添加自定义方法会给你的对象提供自定义的“行级”操作能力
重写模型方法
模型的方法可以被重写以方便定制需求
官方文档
https://docs.djangoproject.com/zh-hans/3.0/topics/db/models/#overriding-predefined-model-methods
执行原生SQL
执行原生SQL使用 Manager.raw()
或 django.db.connection
对象
模型继承
模型继承与普通类继承工作方式几乎完全相同,它可以单继承或者多继承
官方示例:
class CommonInfo(models.Model):
name = models.CharField(max_length=100)
age = models.PositiveIntegerField()
class Meta:
abstract = True
class Student(CommonInfo):
home_group = models.CharField(max_length=5)
抽象基类
编写模型基类,并在 Meta 类中填入 abstract=True
。该模型将不会创建任何数据表,然后在字类模板中继承它。
官方示例:
from django.db import models
class CommonInfo(models.Model):
name = models.CharField(max_length=100)
age = models.PositiveIntegerField()
class Meta:
abstract = True
class Student(CommonInfo):
home_group = models.CharField(max_length=5)
Meta 继承
Meta也可以被继承
官方示例:
class CommonInfo(models.Model):
# ...
class Meta:
abstract = True
ordering = ['name']
class Student(CommonInfo):
# ...
class Meta(CommonInfo.Meta):
db_table = 'student_info'
代理模型
代理模型继承中子类只用于管理父类的数据,而不实际存储数据
一个代理模型必须继承自一个非抽象模型类;一个代理模型可以继承任意数量的抽象模型类
官方示例:
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
class MyPerson(Person):
class Meta:
proxy = True
def do_something(self):
# ...
pass