Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django选择字段意外行为(错误?)_Django - Fatal编程技术网

Django选择字段意外行为(错误?)

Django选择字段意外行为(错误?),django,Django,在Django 1.7的迁移过程中,我遇到了一些奇怪的行为。这是一个应该报告的合法错误吗 总之:我使用了一个模块级选择字段,我最初在一个模型类中引用了该字段。接下来,我做了一些修改,并引用了另一个模型类中的选项集。在迁移中,这不仅导致添加新字段,还导致更改现有字段,从而不再引用选项集 解决这个问题的唯一方法是添加一个重复的选择集(使用不同的名称)并引用各个模型中的不同选择集 初始代码: GRADE_CHOICES = zip(range(1, 7), range(1, 7)) # grade 1

在Django 1.7的迁移过程中,我遇到了一些奇怪的行为。这是一个应该报告的合法错误吗

总之:我使用了一个模块级选择字段,我最初在一个模型类中引用了该字段。接下来,我做了一些修改,并引用了另一个模型类中的选项集。在迁移中,这不仅导致添加新字段,还导致更改现有字段,从而不再引用选项集

解决这个问题的唯一方法是添加一个重复的选择集(使用不同的名称)并引用各个模型中的不同选择集

初始代码:

GRADE_CHOICES = zip(range(1, 7), range(1, 7))
# grade 1 to 6


class ModelA(models.Model):
    name = models.CharField(max_length=50)


class ModelB(models.Model):
    name = models.CharField(max_length=10)
    grade = models.IntegerField(choices=GRADE_CHOICES)
这正如预期的那样有效。接下来是模型更改:

GRADE_CHOICES = zip(range(1, 7), range(1, 7))


class ModelA(models.Model):
    name = models.CharField(max_length=50)
    grade = models.IntegerField(choices=GRADE_CHOICES)
    # ^ this line is added


class ModelB(models.Model):
    name = models.CharField(max_length=10)
    grade = models.IntegerField(choices=GRADE_CHOICES)
由此产生的迁移将字段和选项添加到ModelA(如预期的那样),但将选项从ModelB中删除,将其简化为一个整数字段。这是解决这个问题的唯一方法

GRADE_CHOICES = zip(range(1, 7), range(1, 7))
GRADE_CHOICES_DUPLICATE = zip(range(1, 7), range(1, 7))
# Do Repeat Yourself


class ModelA(models.Model):
    name = models.CharField(max_length=50)
    grade = models.IntegerField(choices=GRADE_CHOICES)
    # ^ this line is added


class ModelB(models.Model):
    name = models.CharField(max_length=10)
    grade = models.IntegerField(choices=GRADE_CHOICES_DUPLICATE)
所以问题是:这种行为是否出人意料。有人愿意尝试复制这个吗

此外,编辑: 选择集的丢失反映在迁移中,如下所示:

operations = [
    migrations.AddField(
        model_name='modelA',
        name='grade',
        field=models.IntegerField(choices=[(1, 1), (2, 2), (3, 3) ]),
    ),
    migrations.AlterField(
        model_name='modelB',
        name='grade',
        field=models.IntegerField(),
    ),
]

有问题的部分是AlterField部分,其中的选项现在被省略。我知道数据库不会有什么不同,但它确实会导致Django管理界面出现错误。

如果您使用的是Python 3,则返回一个迭代器

>>> GRADE_CHOICES = zip(range(1, 7), range(1, 7))
>>> print(GRADE_CHOICES)
<zip object at 0x7fd0dffd8308>
您可以通过在模型中列出GRADE_选项来解决此问题

GRADE_CHOICES = list(zip(range(1, 7), range(1, 7)))

什么意思,迁移从字段中删除了选项?对于一个有选项的字段,您不需要迁移,它们根本不反映在数据库中。不过,它们似乎反映在迁移中。我将用上一次迁移的相关部分更新我的问题。你在管理中遇到了什么错误?@rnevius我将不得不重现确切的错误,但实际情况是:“等级”字段显示为空下拉框[----],不接受任何选择。我验证了底层数据库表仍然正确填充。在尝试在管理员中保存实例时,错误显示为“grade”字段是必需的。我确实使用了Python3,问题得到了解决。谢谢@Alasdair
GRADE_CHOICES = list(zip(range(1, 7), range(1, 7)))