8.Django模型详解

上节我们初步认识了Django的数据库和模型执行,也会基本使用了,本届我们详细介绍一下model类。

首先我们回顾一下上节定义的News模型。

class News(models.Model):
    title = models.CharField(max_length=50)
    content = models.TextField()

    def __str__(self):
        return self.title

我们定义了两个字段title和content。 title是CharField,content是TextField其中title设置了最大长度50. max_length称为字段选项。

1.字段选项

  • null:如果设置为 True , 当该字段为空时,Django会将数据库中该字段设置为 NULL 。默认为 False 。
  • blank:如果设置为 True ,该字段允许为空。默认为 False 。
    null和blank区别:
    注意该选项与 False 不同, null 选项仅仅是数据库层面的设置,然而 blank 是涉及表单验证方面。如果一个字段设置为 blank=True ,在进行表单验证时,接收的数据该字段值允许为空,而设置为 blank=False 时,不允许为空。
  • choices:该参数接收一个可迭代的列表或元组(基本单位为二元组)。如果指定了该参数,在实例化该模型时,该字段只能取选项列表中的值。
    类似枚举
    season = [ 'spring', 'summer', 'autumn', 'winter' ]
  • default: 该字段的默认值。可以是一个值或者是个可调用的对象,如果是个可调用对象,每次实例化模型时都会调用该对象。
  • help_text: 展示在界面上 提示性文字
  • primary_key:如果设置为 True ,将该字段设置为该模型的主键。 如果没有设置Django自动添加一个id为 IntegerField的主键。
  • unique:如果设置为 True,这个字段必须在整个表中保持值唯一。

1.1自动设置主键

默认情况下会设置

id = models.AutoField(primary_key=True)

1.2备注名称

除了 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 参数:

news = 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 值首字母大写,必要时 Djanog 会自动把首字母转换为大写。

2.字段

除了CharField还有

  • AutoField
  • BigAutoField
  • BigIntegerField
  • BooleanField
  • DateField
  • DateTimeField
  • EmailField
  • ...

更多参考:https://docs.djangoproject.com/zh-hans/2.2/ref/models/fields/

3.关联关系

在Django中提供:多对一,多对多,一对一。
关系型数据库的强大之处在于各表之间的关联关系。
关系就是:model和model之间的联系

3.1 Many-to-one

定义一个多对一的关联关系,使用 django.db.models.ForeignKey 类。就和其他 Field 字段类型一样,只需要在你模型中添加一个值为该类的属性。
例如,如果一个 Car 模型 有一个制造者 Manufacturer --就是说一个 Manufacturer 制造许多辆车,但是每辆车都属于某个特定的制造者-- 那么使用下面的方法定义这个关系:

from django.db import models

class Manufacturer(models.Model):
    # ...
    pass

class Car(models.Model):
    # 第一个参数也可以用字符串'Manufacturer'
    # 多对一的关系要写在多的一边
    manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
    # ...

3.2 Many-to-many

定义一个多对多的关联关系,使用 django.db.models.ManyToManyField 类。就和其他 Field 字段类型一样,只需要在你模型中添加一个值为该类的属性。
例如:如果 Pizza 含有多种 Topping(配料) -- 也就是一种Topping 可能存在于多个 Pizza 中,并且每个 Pizza 含有多种 Topping --那么可以这样表示这种关系:

from django.db import models

class Topping(models.Model):
    # ...
    pass

class Pizza(models.Model):
    # 关系也可以写在Topping中,但是不能两个都写
    toppings = models.ManyToManyField(Topping)

3.3 One-to-one

使用 OneToOneField 来定义一对一关系。就像使用其他类型的 Field 一样:在模型属性中包含它。

当一个对象以某种方式“扩展”另一个对象时,这对该对象的主键非常有用。

OneToOneField 需要一个位置参数:与模型相关的类。

例如,当你要建立一个有关“位置”信息的数据库时,你可能会包含通常的地址,电话等字段。接着,如果你想接着建立一个关于关于餐厅的数据库,除了将位置数据库当中的字段复制到 Restaurant 模型,你也可以将一个指向 Place OneToOneField 放到 Restaurant 当中(因为餐厅“是一个”地点);事实上,在处理这样的情况时最好使用 inheritance ,它隐含的包括了一个一对一关系。

from django.db import models

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

    def __str__(self):
        return "%s the place" % self.name

class Restaurant(models.Model):
    place = models.OneToOneField(
        Place,
        on_delete=models.CASCADE,
        primary_key=True,
    )
    serves_hot_dogs = models.BooleanField(default=False)
    serves_pizza = models.BooleanField(default=False)

    def __str__(self):
        return "%s the restaurant" % self.place.name

class Waiter(models.Model):
    restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
    name = models.CharField(max_length=50)

    def __str__(self):
        return "%s the waiter at %s" % (self.name, self.restaurant)

本文参考:https://docs.djangoproject.com/zh-hans/2.2/topics/db/models/

下一节

9.数据库查询

声明:原创文章,版权所有,转载请注明出处,https://litets.com。