from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
first_name 和 last_name 是模型的 字段。每个字段都被指定为一个类属性,并且每个属性映射为一个数据库列。
上面的 Person 模型会创建一个如下的数据库表:
CREATE TABLE myapp_person (
"id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL
一些技术上的说明:
该表的名称 myapp_person 是自动从某些模型元数据中派生出来,但可以被改写。参阅 表名称 获取更多信息。
一个 id 字段会被自动添加,但是这种行为可以被改写。请参阅 自动设置主键。
本例子中 创建数据表 的语法是 PostgreSQL 格式的。值得注意的是,Django 依据你在 配置文件 中指定的数据库后端生成对应的 SQL 语句。
使用模型
一旦你定义了你的模型,你需要告诉 Django 你准备 使用 这些模型。你需要修改设置文件中的 INSTALLED_APPS ,在这个设置中添加包含 models.py 文件的模块名称。
例如,若模型位于项目中的 myapp.models 模块( 此包结构由 manage.py startapp 命令创建), INSTALLED_APPS 应设置如下:
INSTALLED_APPS = [
# ...
"myapp",
# ...
当你向 INSTALLED_APPS 添加新的应用的时候,请务必运行 manage.py migrate,此外你也可以先使用以下命令进行迁移 manage.py makemigrations。
模型中最重要且唯一必要的是数据库的字段定义。字段在类属性中定义。定义字段名时应小心避免使用与 模型 API 冲突的名称, 如 clean, save, or delete 等.
from django.db import models
class Musician(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
instrument = models.CharField(max_length=100)
class Album(models.Model):
artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
release_date = models.DateField()
num_stars = models.IntegerField()
字段类型
模型中每一个字段都应该是某个 Field 类的实例, Django 利用这些字段类来实现以下功能:
字段类型用以指定数据库数据类型(如:INTEGER, VARCHAR, TEXT)。
在渲染表单字段时默认使用的 HTML 视图 (如: <input type="text">, <select>)。
基本的有效性验证功能,用于 Django 后台和自动生成的表单。
Django 内置了数十种字段类型;你可以在 模型字段参考 中看到完整列表。如果 Django 内置类型不能满足你的需求,你可以很轻松地编写自定义的字段类型;参见 编写自定义模型字段。
字段选项
每一种字段都需要指定一些特定的参数(参考 模型字段 )。 例如, CharField (以及它的子类)需要接收一个 max_length 参数,用以指定数据库存储 VARCHAR 数据时用的字节数。
一些可选的参数是通用的,可以用于任何字段类型,详情请见 参考 ,下面介绍一部分经常用到的通用参数:
null如果设置为 True,当该字段为空时,Django 会将数据库中该字段设置为 NULL。默认为 False 。
blank如果设置为 True,该字段允许为空。默认为 False。
请注意,这与 null 不同。null 完全与数据库相关联,而 blank 与验证有关。如果字段具有 blank=True,表单验证将允许输入空值。如果字段具有 blank=False,则字段为必填项。
choices一个 2 值元组的 sequence,一个 mapping,一个 枚举类型,或者一个可调用对象(不接受参数并返回前述任意格式之一),用作此字段的选择项。如果提供了此参数,则默认的表单小部件将是选择框,而不是标准文本字段,并且将限制选择范围为给定的选择项。
一个选项列表:
YEAR_IN_SCHOOL_CHOICES = [
("FR", "Freshman"),
("SO", "Sophomore"),
("JR", "Junior"),
("SR", "Senior"),
("GR", "Graduate"),
每当 choices 的顺序变动时将会创建新的迁移。
每个二元组的第一个值会储存在数据库中,而第二个值将只会用于在表单中显示。
对于一个模型实例,要获取该字段二元组中相对应的第二个值,使用 get_FOO_display() 方法。例如:
from django.db import models
class Person(models.Model):
SHIRT_SIZES = {
"S": "Small",
"M": "Medium",
"L": "Large",
name = models.CharField(max_length=60)
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
>>> p = Person(name="Fred Flintstone", shirt_size="L")
>>> p.save()
>>> p.shirt_size
>>> p.get_shirt_size_display()
'Large'
你也可以使用枚举类以简洁的方式来定义 choices :
from django.db import models
class Runner(models.Model):
MedalType = models.TextChoices("MedalType", "GOLD SILVER BRONZE")
name = models.CharField(max_length=60)
medal = models.CharField(blank=True, choices=MedalType, max_length=10)
model field reference 中定义了更多的示例。
default该字段的默认值。可以是一个值或者是个可调用的对象,如果是个可调用对象,每次实例化模型时都会调用该对象。
db_default字段的数据库计算的默认值。这可以是一个字面值或一个数据库函数。
如果同时设置了 db_default 和 Field.default,在 Python 代码中创建实例时 default 会优先生效。db_default 仍然会在数据库级别设置,并且在使用 ORM 之外插入行或在迁移中添加新字段时仍然会使用它。
help_text额外的“帮助”文本,随表单控件一同显示。即便你的字段未用于表单,它对于生成文档也是很有用的。
primary_key如果设置为 True ,将该字段设置为该模型的主键。
If you don't specify primary_key=True for
any fields in your model, Django will automatically add a field to hold
the primary key, so you don't need to set
primary_key=True on any of your fields
unless you want to override the default primary-key behavior. For more,
see 自动设置主键.
主键字段是只可读的,如果你修改一个模型实例的主键并保存,这等同于创建了一个新的模型实例。例如:
from django.db import models
class Fruit(models.Model):
name = models.CharField(max_length=100, primary_key=True)
>>> fruit = Fruit.objects.create(name="Apple")
>>> fruit.name = "Pear"
>>> fruit.save()
>>> Fruit.objects.values_list("name", flat=True)
<QuerySet ['Apple', 'Pear']>
unique如果设置为 True,这个字段的值必须在整个表中保持唯一。
再次声明,以上只是一些通用参数的简略描述。你可以在 通用可选参数参考 中找到完整的介绍。
自动设置主键
默认情况下,Django 给每个模型一个自动递增的主键,其类型在 AppConfig.default_auto_field 中指定,或者在 DEFAULT_AUTO_FIELD 配置中全局指定。例如:
id = models.BigAutoField(primary_key=True)
如果你想自己指定主键, 在你想要设置为主键的字段上设置参数 primary_key=True。如果 Django 看到你显式地设置了 Field.primary_key,将不会自动在表(模型)中添加 id 列。
每个模型都需要拥有一个设置了 primary_key=True 的字段(无论是显式的设置还是 Django 自动设置)。
字段备注名
除了 ForeignKey, ManyToManyField 和 OneToOneField,任何字段类型都接收一个可选的位置参数 verbose_name,如果未指定该参数值, Django 会自动使用字段的属性名作为该参数值,并且把下划线转换为空格。
在该例中:备注名为 "person's first name":
first_name = models.CharField("person's first name", max_length=30)
在该例中:备注名为 "first name":
first_name = models.CharField(max_length=30)
ForeignKey, ManyToManyField and OneToOneField 接收的第一个参数为模型的类名,后面可以添加一个 verbose_name 参数:
poll = models.ForeignKey(
Poll,
on_delete=models.CASCADE,
verbose_name="the related poll",
sites = models.ManyToManyField(Site, verbose_name="list of sites")
place = models.OneToOneField(
Place,
on_delete=models.CASCADE,
verbose_name="related place",
惯例是不将 verbose_name 的首字母大写,必要时 Django 会自动把首字母转换为大写。
关联关系
显然,关系型数据库的强大之处在于各表之间的关联关系。 Django 提供了定义三种最常见的数据库关联关系的方法:多对一,多对多,一对一。
多对一关联
定义一个多对一的关联关系,使用 django.db.models.ForeignKey 类。就和其它 Field 字段类型一样,只需要在你模型中添加一个值为该类的属性。
ForeignKey 类需要添加一个位置参数,即你想要关联的模型类名。
例如,如果一个 Car 模型有一个制造者 Manufacturer --就是说一个 Manufacturer 制造许多辆车,但是每辆车都仅有一个制造者-- 那么使用下面的方法定义这个关系:
from django.db import models
class Manufacturer(models.Model):
# ...
class Car(models.Model):
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
# ...
你也可以创建 自关联关系 (一个模型与它本身有多对一的关系)和 与未定义的模型间的关联关系 ;详情请见 模型字段参考 。
建议设置 ForeignKey 字段名(上例中的 manufacturer )为想要关联的模型名,但是你也可以随意设置为你想要的名称,例如:
class Car(models.Model):
company_that_makes_it = models.ForeignKey(
Manufacturer,
on_delete=models.CASCADE,
# ...
See also
ForeignKey
字段还可以接收一些其他的参数,详见 模型字段参考 ,这些可选的参数可以更深入的规定关联关系的具体实现。
关于反向关联对象的细节,参见 反向关联例子。
如要查看相关示例代码,详见 模型多对一关联实例 。
多对多关联
定义一个多对多的关联关系,使用 django.db.models.ManyToManyField 类。就和其他 Field 字段类型一样,只需要在你模型中添加一个值为该类的属性。
ManyToManyField 类需要添加一个位置参数,即你想要关联的模型类名。
例如:如果 Pizza 含有多种 Topping (配料) -- 也就是一种 Topping 可能存在于多个 Pizza 中,并且每个 Pizza 含有多种 Topping --那么可以这样表示这种关系:
from django.db import models
class Topping(models.Model):
# ...
class Pizza(models.Model):
# ...
toppings = models.ManyToManyField(Topping)
和 ForeignKey 类一样,你也可以创建 自关联关系 (一个对象与他本身有着多对多的关系)和 与未定义的模型的关系 。
建议设置 ManyToManyField 字段名(上例中的 toppings )为一个复数名词,表示所要关联的模型对象的集合。
对于多对多关联关系的两个模型,可以在任何一个模型中添加 ManyToManyField 字段,但只能选择一个模型设置该字段,即不能同时在两模型中添加该字段。
一般来讲,应该把 ManyToManyField 实例放到需要在表单中被编辑的对象中。在之前的例子中, toppings 被放在 Pizza 当中(而不是 Topping 中有指向 pizzas 的 ManyToManyField 实例 )因为相较于配料被放在不同的披萨当中,披萨当中有很多种配料更加符合常理。按照先前说的,在编辑 Pizza 的表单时用户可以选择多种配料。
See also
如要查看完整示例代码,详见 模型多对多关联实例。
ManyToManyField 字段也接受一些 模型字段参考 中介绍的参数。这些可选的参数可以更深入地规定关联关系的具体实现。