【问题标题】:Django creates pointless migrations on choices list changeDjango 在选择列表更改时创建毫无意义的迁移
【发布时间】:2023-03-28 14:56:01
【问题描述】:

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

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

在哪里

SEVERITY_CHOICES = (
    (1, 'Low'),
    (2, 'Medium'),
    (3, 'High'),
)

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

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

【问题讨论】:

  • 对于参数选择,唯一可接受的字段是元组,或者有时可以是列表,但在这里你试图传递一个类并回顾参考,尝试将 SEVERITY_CHOICES 的名称更改为 get_severity_choices。
  • 我认为您可以将for item in SEVERITY_CHOICES: yield item 替换为return iter(SEVERITY_CHOICES)。甚至severity = models.IntegerField(choices=SEVERITY_CHOICES)

标签: python django


【解决方案1】:

我认为您混淆了 Model 字段上的 choices 参数和 forms.ChoiceField 字段上的参数。在model 中,choices 必须是一个可交互对象——你不能传递一个可调用对象:

choices: 一个可迭代对象(例如,一个列表或元组),它由自身的可迭代对象组成 恰好有两个项目(例如 [(A, B), (A, B) ...])用作选择 这个字段。

您的 get_severity_choices 类未被识别为可迭代,因为 Django 期望它继承 collections.Iterable 而不仅仅是公开 __iter__ 方法。

可以a callable 传递给FormField

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

但是,对于Model 字段,您必须事先指定您的选择。同样来自文档:

注意choices 可以是任何可迭代对象——不一定是列表 或元组。这使您可以动态构建选择。但如果你发现 你自己黑客choices 是动态的,你可能会更好 使用带有 ForeignKey 的适当数据库表。 choices 用于 变化不大的静态数据,如果有的话。

关于 Django 为什么会创建看似无用的迁移,this ticket 中有一些讨论:

这是设计使然。有几个原因,其中最重要的是......历史上的数据迁移需要有一个完整的 模型的准确表示,包括它们的所有选项,而不是 只是那些影响数据库的。

【讨论】:

    猜你喜欢
    • 2015-10-25
    • 2013-06-09
    • 1970-01-01
    • 2015-09-15
    • 2015-01-22
    • 2019-10-27
    • 2015-10-19
    • 2011-10-03
    • 2017-01-08
    相关资源
    最近更新 更多