Django在选择列表更改时创建无意义的迁移

And*_*rew 2 python django

我正在尝试使用可调用对象来创建带有选项字段的模型,以便当选项列表更改时,Django不会创建迁移,如问题所述。

class Quote(models.Model):
    severity = models.IntegerField(choices=get_severity_choices)
    ...

class get_severity_choices(object):
    def __iter__(self):
        for item in SEVERITY_CHOICES:
            yield item
Run Code Online (Sandbox Code Playgroud)

哪里

SEVERITY_CHOICES = (
    (1, 'Low'),
    (2, 'Medium'),
    (3, 'High'),
)
Run Code Online (Sandbox Code Playgroud)

但是,我收到一条错误消息:

quoting.Quote.severity: (fields.E004) 'choices' must be an iterable (e.g., a list or tuple).
Run Code Online (Sandbox Code Playgroud)

sol*_*oke 6

我认为您正在混淆choices一个Model字段和一个字段的论点forms.ChoiceField。在模型中choices必须是可互操作的-您不能传递可调用对象:

choices:一个由完全由两个项目(例如[[(A,B),(A,B)...])组成的可迭代对象组成的可迭代对象(例如列表或元组),用作该字段的选择。

您的get_severity_choices类不会被认为是可迭代的,因为Django希望它是子类的,collections.Iterable而不仅仅是公开一个__iter__方法。

可以Callable传递给FormField

choices:要么是一个2元组的可迭代对象(例如,列表或元组),用作此字段的选择,要么是一个可返回该可迭代对象的可调用对象。

Model但是,对于字段,您必须事先指定选择。另外从文档:

请注意,它choices可以是任何可迭代的对象–不一定是列表或元组。这使您可以动态构造选择。但是,如果您发现黑客攻击choices是动态的,那么最好使用带有ForeignKey的正确数据库表。choices表示静态数据,它们不会发生太大变化(如果有的话)。

关于Django为什么创建看似无用的迁移的原因,此票证对此进行了一些讨论:

这是设计使然。原因有很多,其中不仅仅如此……历史上各个点的数据迁移都需要对模型进行完全准确的表示,包括其所有选项,而不仅仅是影响数据库的那些。