Django 中的模型

已完成

模型是所有 ORM 的核心。 模型是应用程序将要处理的数据的表现形式。 可以是人员、产品、类别或应用程序所需的任何其他形式的数据。

创建模型

在 Django 中,模型是从 django.models.Model 继承功能集合的任何类。 该集合包含多种方法,你可以使用这些方法来查询数据库,创建新条目以及保存更新。 还可以定义字段,设置元数据以及在模型之间建立关系。

如果想创建 ProductCategory 两个模型,则需要添加两个类:

from django.db import models
class Product(models.Model):
    # details would go here
    pass

class Category(models.Model):
    # details would go here
    pass

添加方法

在我们讨论如何为模型配置数据之前,需要强调的是模型属于 Python 类。 因此,你既可以添加方法,也可以覆盖 Django.models.Model 提供的或所有 Python 对象固有的方法。

尤其要强调的一种方法是 __str__。 未指定任何字段的情况下,可以使用此方法显示对象。 如果 Productname 字段(稍后我们将看到),你可以通过重写 __str__ 将其作为 Product 默认字符串表示形式返回。

class Product(models.Model):
    name = models.TextField()
    
    def __str__(self):
        return self.name

添加字段

字段定义模型的数据结构。 字段可能包括项目名称、创建日期、价格或模型需要存储的任何其他数据片段。

不同的数据片段具有不同的数据类型、验证规则和其他形式的元数据。 Django ORM 包含一组丰富的选项,你可以根据规范使用这些选项来配置模型的字段。 ORM 是可扩展的,因此可以根据需要创建自己的规则。

定义字段类型

所有字段的元数据的核心部分都是它将存储的数据类型,如字符串或数字。 字段类型映射到数据库类型和 HTML 表单控件类型(如文本框或复选框)。 Django 包括多个字段类型,如:

  • CharField:单行文本。
  • TextField:多行文本。
  • BooleanField:布尔 true/false 选项。
  • DateField:日期。
  • TimeField:时间。
  • DateTimeField:日期和时间。
  • URLField:URL。
  • IntegerField:整数。
  • DecimalField:固定精度的十进制数。

要将字段添加到 ProductCategory 类,可能会使用以下代码:

from django.db import models
class Product(models.Model):
    name = models.TextField()
    price = models.DecimalField()
    creation_date = models.DateField()

class Category(models.Model):
    name = models.TextField()

字段选项

你可以使用字段选项添加允许 NULL 或空白值的元数据,或将字段标记为唯一。 还可以设置验证选项并为验证错误提供自定义消息。

与字段类型一样,字段选项会映射到数据库中的相应设置。 规则将在 Django 为你生成的任何表单中强制执行。

字段选项会传递到字段本身的函数中。 不同字段可能支持不同的选项。 常见的选项有:

  • null
    • 允许 NULL 值的布尔选项。
    • 默认值为 False
  • blank
    • 允许空白值的布尔选项。
    • 默认值为 False
  • default
    • 如果未提供字段的值,则允许配置默认值。
    • 如果要将默认值设置为数据库 null,请将 default 设置为 None
  • unique
    • 此字段必须包含一个唯一值。
    • 默认值为 False
  • min_lengthmax_length
    • 与字符串类型一起用于识别最小和最大的字符串长度。
    • 默认值为 None
  • min_valuemax_value
    • 与数字类型一起用于识别最小和最大的值。
  • auto_nowauto_now_add
    • 与日期/时间类型一起用于指示是否应该使用当前时间。
    • auto_now 始终在保存时将字段设置为当前时间,这对 last_update 字段很有帮助。
    • auto_now_add 始终在创建时将字段设置为当前时间,这对 creation_date 字段很有帮助。

备注

nullblank 看起来相似,但在数据库术语中有不同含义。 null 是指缺少值,而 blank 专指空值。

要将选项添加到模型,代码如下所示:

from django.db import models
class Product(models.Model):
    name = models.TextField(max_length=50, min_length=3, unique=True)
    price = models.DecimalField(min_value=0.99, max_value=1000)
    creation_date = models.DateField(auto_now_add=True)

class Category(models.Model):
    name = models.TextField(max_length=50, min_length=3, unique=True)

键和关系

在关系数据库中,标准做法是表中的每一行都有一个主键,通常是自动递增的整数。 Django 的 ORM 会自动将此键添加到你创建的每个模型,方法是添加一个名为 id 的字段。

如果要重写此行为,可以将你想使用的字段设置为主键。 但在大多数情况下,你应该依赖 Django 的 id 字段。

关系数据库还包含表之间的关系。 产品对应类别,员工对应经理,而汽车对应制造商。 Django 的 ORM 支持所有你想要在模型之间创建的关系。

最常见的关系是“一对多”,在技术层面上称为外键关系。 在外键关系中,多个项目共享一个特性。 例如,将多个产品分组到一个类别。 要为此关系建模,请使用 ForeignKey 字段。

要创建关系,请将 ForeignKey 字段添加到子对象。 如果产品被分组到多个类别,则为 Product 类添加 category 属性,并将类型设置为 ForeignKey

Django 自动为父级添加属性,以提供对名为 <child>_set 的所有子级的访问权限,其中 <child> 是子对象的名称。 在我们的示例中,Category 将自动添加 product_set,以提供对类别中所有产品的访问权限。

ForeignKey 有一个必需参数 on_delete。 此参数向 Django 表明在删除父级时要执行的操作。 也就是说,如果我们删除类别,会对该类别的产品造成什么影响?

两种最常见的选项是:

  • CASCADE,如果在示例中删除了某个类别,则将删除所有产品。
  • PROTECT,如果尝试删除包含产品的某个类别,则将返回错误。

备注

在大多数情况,你会使用 PROTECT

可以使用以下代码来更新模型以创建关系:

from django.db import models
class Product(models.Model):
    name = models.TextField()
    price = models.DecimalField()
    creation_date = models.DateField()
    category = models.ForeignKey(
        'Category', #The name of the model
        on_delete=models.PROTECT
    )

class Category(models.Model):
    name = models.TextField()
    # product_set will be automatically created