Django模型(model)详解:设置主键、字段备注名

3,296 阅读2分钟

这是我参与更文挑战的第10天,活动详情查看: 更文挑战

什么是主键?

在数据库中,主键是每一条记录的唯一识别号,用来区分不同的记录,因此如果有主键,则主键不能重复。

可以没有主键吗?

原生的数据库是可以没有主键的,但是在Django中,模型一定会有主键,即使自己不设定主键,Django也会自动添加一个主键。每个模型都需要拥有一个设置了 primary_key=True 的字段(无论是显式的设置还是 Django 自动设置)。

手动设置主键

  • 如果你想自己指定主键, 在你想要设置为主键的字段上设置参数 primary_key=True
  • primary_key=True 意味着 null=Falseunique=True,即主键必须非空且唯一。
  • 一个对象只允许有一个主键。
from django.db import models

class Fruit(models.Model):
    name = models.CharField(max_length=100, primary_key=True)

自动设置主键

默认情况下,Django 给每个模型一个自动递增的主键,如果有显式地设置了 Field.primary_keyprimary_key=True),将不会自动在表(模型)中添加 id 列(属性)。

  • 自动主键的类型:

    • AutoField(默认类型):一个 IntegerField,根据可用的 ID 自动递增。通常不需要直接使用它;如果没有指定,主键字段会自动添加到你的模型中。
    • BigAutoField:一个 64 位整数,与 AutoField 很相似,但保证适合 1 到 9223372036854775807 的数字
  • 全局设置默认主键类型:配置(setting.py)中设置DEFAULT_AUTO_FIELD

DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
# Django 3.2 新特性
  • 局部设置默认主键类型:应用中的apps.py模块中设置AppConfig.default_auto_field (默认取全局的DEFAULT_AUTO_FIELD)
# anthology/apps.py 应用中的apps.py模块
from rock_n_roll.apps import RockNRollConfig

class JazzManoucheConfig(RockNRollConfig):
   default_auto_field = 'django.db.models.AutoField'
   # Django 3.2 新特性


# anthology/settings.py 项目的配置文件setting.py
INSTALLED_APPS = [
   'anthology.apps.JazzManoucheConfig',
   # ...
]

字段备注名verbose_name

除了外键字段(ForeignKey、ManyToManyField、neToOneField),任何字段类型都接收第一个可选的位置参数 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、neToOneField)也可以设置备注名:先第一个参数传入类名,再传入verbose_name参数。

poll = models.ForeignKey(
    Poll,    #  第一个参数为模型的类名
    on_delete=models.CASCADE,
    verbose_name="the related poll",    #  后面添加一个 verbose_name 参数:
)
sites = models.ManyToManyField(Site, verbose_name="list of sites")
place = models.OneToOneField(
    Place,
    on_delete=models.CASCADE,
    verbose_name="related place",
)

惯例是不将 verbose_name 的首字母大写,必要时 Djanog 会自动把首字母转换为大写。