为什么在 Django 模型中使用 Choices 时要设置 max_length?
Why should I set max_length when using Choices in a Django model?
在官方Django 2 tutorial中我发现了这个:
from django.db import models
class Student(models.Model):
FRESHMAN = 'FR'
SOPHOMORE = 'SO'
JUNIOR = 'JR'
SENIOR = 'SR'
YEAR_IN_SCHOOL_CHOICES = (
(FRESHMAN, 'Freshman'),
(SOPHOMORE, 'Sophomore'),
(JUNIOR, 'Junior'),
(SENIOR, 'Senior'),
)
year_in_school = models.CharField(
max_length=2,
choices=YEAR_IN_SCHOOL_CHOICES,
default=FRESHMAN,
)
现在我的问题是使用 choices 是否意味着只有四个定义值中的一个对该字段有效?如果是这样,指定 max_length
有什么用?如果不是,为什么不使用一个验证器来验证该值是否确实是指定值之一,或者至少是一个只接受特定长度而不仅仅是上限的验证器。
max_length
is enforced at the database level, but the choices
在 python 代码级别强制执行(调用 full_clean()
或 clean_<fieldname>()
时)。
它们是相互独立的。
如果您为您的字段设置了指定选项以外的值并且您不调用instance.full_clean()
或instance.clean_<fieldname>()
,它仍然可以获得已保存到数据库而不会引发错误。
但如果您使用 djangos 表单,choices
验证已经为您完成(表单调用 full_clean()
),您无需担心。
这意味着,例如,如果您将 max_length
设置为小于 choices
中的最大选项,您的数据库将自动截断该字段的值或引发 DatabaseError
;无论哪种方式,你都不会让它工作。
这种分离很有用,例如,如果你以后想添加更多的选择;如果新选项不大于 max_length
,则无需更改数据库结构(这意味着新迁移将 NOT 发布 alter table
SQL 个陈述)。
我最近 运行 遇到了这个问题,除了我不只是使用两个字母的代码所以确保我有一个有效的 max_length 有点乏味。我最终做了这样的事情:
year_in_school = models.CharField(
max_length=max(len(v[0]) for v in YEAR_IN_SCHOOL_CHOICES),
choices=YEAR_IN_SCHOOL_CHOICES,
default=FRESHMAN,
)
如果我添加的选项超过了现有的最大长度,makemigrations 会检测到并将该更改添加到迁移中。
在官方Django 2 tutorial中我发现了这个:
from django.db import models
class Student(models.Model):
FRESHMAN = 'FR'
SOPHOMORE = 'SO'
JUNIOR = 'JR'
SENIOR = 'SR'
YEAR_IN_SCHOOL_CHOICES = (
(FRESHMAN, 'Freshman'),
(SOPHOMORE, 'Sophomore'),
(JUNIOR, 'Junior'),
(SENIOR, 'Senior'),
)
year_in_school = models.CharField(
max_length=2,
choices=YEAR_IN_SCHOOL_CHOICES,
default=FRESHMAN,
)
现在我的问题是使用 choices 是否意味着只有四个定义值中的一个对该字段有效?如果是这样,指定 max_length
有什么用?如果不是,为什么不使用一个验证器来验证该值是否确实是指定值之一,或者至少是一个只接受特定长度而不仅仅是上限的验证器。
max_length
is enforced at the database level, but the choices
在 python 代码级别强制执行(调用 full_clean()
或 clean_<fieldname>()
时)。
它们是相互独立的。
如果您为您的字段设置了指定选项以外的值并且您不调用instance.full_clean()
或instance.clean_<fieldname>()
,它仍然可以获得已保存到数据库而不会引发错误。
但如果您使用 djangos 表单,choices
验证已经为您完成(表单调用 full_clean()
),您无需担心。
这意味着,例如,如果您将 max_length
设置为小于 choices
中的最大选项,您的数据库将自动截断该字段的值或引发 DatabaseError
;无论哪种方式,你都不会让它工作。
这种分离很有用,例如,如果你以后想添加更多的选择;如果新选项不大于 max_length
,则无需更改数据库结构(这意味着新迁移将 NOT 发布 alter table
SQL 个陈述)。
我最近 运行 遇到了这个问题,除了我不只是使用两个字母的代码所以确保我有一个有效的 max_length 有点乏味。我最终做了这样的事情:
year_in_school = models.CharField(
max_length=max(len(v[0]) for v in YEAR_IN_SCHOOL_CHOICES),
choices=YEAR_IN_SCHOOL_CHOICES,
default=FRESHMAN,
)
如果我添加的选项超过了现有的最大长度,makemigrations 会检测到并将该更改添加到迁移中。