如果在 Django 模型中使用 IntegerChoices 字段没有向用户显示,它有什么好处吗?



我在Django(3.2)模型中使用IntegerChoices

class AType(db.IntegerChoices):
UNKNOWN = 0, 'Unknown'
SOMETHING = 1, 'Something'
ANOTHER_THING = 2, 'Another thing'
A_THIRD_THING = 3, 'A third thing'

class MyObject(models.Model):
a_type = db.IntegerField(choices=AType.choices)

(我已将选择更改为更通用)

每当我向AType添加一个值时,它都会产生一个DB迁移,我忠实地应用这个迁移。

a_type严格地在幕后。用户永远不会看到它,所以它只在管理UI中,但我不需要它是可编辑的。所以表单并没有真正使用。

这些迁移对DB(例如,约束)有任何影响吗?

如果IntegerChoices字段不显示给(非人员)用户,也不显示在表单中,那么是否有其他实用程序可以使用该字段?

如果没有实用程序,我正在考虑只是将MyObject.a_type更改为IntegerField,并继续在任何地方使用AType,但没有所有的迁移。

这些迁移对DB(例如,约束)有任何影响吗?

对模式没有影响。您可以在python manage.py sqlmigrate myapp 000x_mymigration中看到这一点。

但是,它仍然执行CREATE TABLE,INSERT INTO ... SELECT(昂贵的),DROP TABLE,ALTER TABLE.

这是"by design"one_answers"wontfix"

  • #22837(迁移检测不必要的(?)更改)- Django
  • #30048(当verbose_name或help_text改变时创建的迁移)- Django

如果IntegerChoices字段不显示给(非人员)用户,也不显示在表单中,那么是否有其他实用程序可以使用该字段?

是的,模型验证。
参考:https://docs.djangoproject.com/en/3.2/ref/models/fields/#choices

我想只是将MyObject.a_type更改为IntegerField,并继续在任何地方使用AType,但没有所有的迁移。

通过在makemigrationsmigrate中修补MigrationAutodetector,可以忽略choices

您还可以忽略_verbose_namehelp_text

mysite/apps.py:

from django.apps import AppConfig
from django.core.management.commands import makemigrations, migrate
from django.db import models
from django.db.migrations import autodetector

class MigrationAutodetector(autodetector.MigrationAutodetector):
ignored_field_attribute_names = [
'choices',
# '_verbose_name',
# 'help_text',
]
def deep_deconstruct(self, obj):
if isinstance(obj, models.Field):
for attr_name in self.ignored_field_attribute_names:
setattr(obj, attr_name, None)
return super().deep_deconstruct(obj)

class MySiteAppConfig(AppConfig):
name = 'mysite'
def ready(self):
makemigrations.MigrationAutodetector = MigrationAutodetector
migrate.MigrationAutodetector = MigrationAutodetector
pass

mysite/settings.py:

INSTALLED_APPS = [
# ...
'mysite.apps.MySiteAppConfig',
]

最新更新