我有两个简单的乡村和城镇模型:
from django.db import models
class Country(models.Model):
name = models.CharField(max_length=50)
class Town(models.Model):
belongs_to = models.ForeignKey(country, on_delete=models.CASCADE)
name = models.CharField(max_length=50)
现在我想玩一玩...我想加上大陆。我想从一开始正确的方法就是这样做:
from django.db import models
class Continent(models.Model):
name = models.CharField(max_length=50)
class Country(models.Model):
belongs_to = models.ForeignKey(continent, on_delete=models.CASCADE)
name = models.CharField(max_length=50)
class Town(models.Model):
belongs_to = models.ForeignKey(country, on_delete=models.CASCADE)
name = models.CharField(max_length=50)
如果我这样做并保存文件,将www.example.com中的continents添加admin.py到admin.site.register(continent),从makemigrations开始...我得到了这个:
您正试图添加一个不可为空的字段“属于”没有默认值的国家;我们不能这样做(数据库需要一些东西来填充现有的行)。请选择修复:
1.)现在提供一个一次性的默认值(将在此列为空值的所有现有行上设置)2.)退出,让我在www.example.com中添加一个默认值models.py
我被困在这里,因为我不知道从这里做什么?
3条答案
按热度按时间83qze16e1#
我认为你得到的信息是相当不言自明的。
您正在将
belongs_to
字段添加到country
模型中(类的名称应该使用第一个大写字母,就像Country
一样),但它被声明为不可空。也就是说,它必须有一个声明的值。现在,因为您已经填充了
country
模型的一些行(对象),Django会询问您应该向这些现有行添加belongs_to
的值。有两种解决方案:
1.将一个整数(它将成为
continent
模型的id
)添加到所有这些变量中,并在以后更改它,或者1.更改为
belongs_to = models.ForeignKey(continent, on_delete=models.CASCADE, null=True, blank=True)
,以便在migrate
之后,此字段可以为空,因此现有行将具有该字段为null
。希望你能理解。
b09cbbtk2#
我经常为此而挣扎。多亏了@nik_m的回答,我才能想出(经过一些测试和失败之后)从一个已经有对象的模型中向一个没有对象的模型添加一个新的ForeignKey的最简单的方法。
1.使字段可为空(如nik_m在上面答案的第2步中所解释的)。
1.创建外部模型的(默认)对象。它将自动具有id=1(如果还不存在对象)。
1.通过将
null=True, blank=True
替换为default=1
来更改外键字段,以将创建的新对象与所有现有行相关联。1.最后,您可以(最终)删除
default=1
,以强制每个新对象在创建时声明外键。6l7fqoea3#
如果您希望新的
ForeignKey
字段从一开始就不可为空,并且能够顺利运行所有迁移,而不会出现错误,并且不需要在中间暂停(例如创建外键记录),可以在迁移文件中添加新记录(用于外键):1.不要在模型的字段上设置
null=True
。1.生成移植文件。
选择 “立即提供一次性默认值”。将引用的外键ID的默认值设置为任意值,例如
1
。该值无关紧要,因为我们稍后将更改它。此时,如果
Country
表中存在现有记录,则运行迁移将失败,因为将Country
的所有记录中的Country.belongs_to
的值设置为不存在的Continent
外键记录(使用您设置为默认值的任何外键ID)将失败。在定义了新
Continent
模型的创建的迁移操作之后,在数据库中创建一条新的Continent
记录。然后,将新的外键belongs_to
字段添加到Country
模型中,并将其值设置为新创建的记录的ID,作为外键的默认值。Continent
表,然后将创建新的Continent
记录,然后将新字段continent_id
外键添加到模型Country
表,其中每个记录的值将设置为所创建的Continent
记录的ID。正如其他人所提到的,另一种选择是使用
null=True
将模型字段声明为可空,迁移(将字段添加到数据库),然后设置字段值(数据库中的每条记录),然后删除null=True
以使其不可空。