【发布时间】:2017-07-22 19:54:27
【问题描述】:
我正在使用 Django 1.10,我有两个这样的模型:
class Model1:
name = models.CharField()
class Model2:
model1 = models.ForeignKey(Model1, default=get_default_model1)
get_default_model1
函数必须获取Model1
的特定实例(例如,具有特定名称),或者如果它不存在则创建它。问题是这个函数会导入Model1
,并且还会在迁移中使用:这意味着当Model1
被修改时,这种迁移可能会中断,因为它将导入Model1
的新版本而不是它需要的版本当时(有关此问题的更好解释,请参阅here)。
在迁移中执行RunPython
操作时,您可以通过apps
参数访问模型的历史版本,但情况并非如此。
我编写了以下代码来手动创建模型的历史版本:
from django.db import models, connection
from django.db.migrations.loader import MigrationLoader
def get_default_model1():
loader = MigrationLoader(connection)
apps = loader.project_state(list(loader.applied_migrations)).apps
Model1 = apps.get_model('app', 'Model1')
return Model1.objects.get_or_create(
name=settings.DEFAULT_NAME,
defaults={'name': settings.DEFAULT_NAME}
)[0].pk
但在某些迁移中,它会因django.db.migrations.exceptions.NodeNotFoundError: Node ('default', '0004_auto_20160423_0400') not a valid node
而失败。它似乎与第三方依赖的替换迁移有关。
有没有更好的方法来获取我的模型的历史版本或完成我在这里尝试做的事情?
【问题讨论】:
-
您能解释一下为什么需要历史模型吗?这样的模型将与数据库不同步,因此可能无法创建外键等
-
我试图在第二段中解释原因,但可能不够清楚。我需要历史版本,因为该函数是字段的默认值,因此它将为该模型创建一个新的迁移。当该迁移运行时,它需要查看当时与数据库同步的模型版本,如果模型随后遭受更多更改,则可能与最新版本不同。
-
这个字段不能设置为null吗?这将使生活更轻松
-
哈,好吧,这会让事情变得更容易,但这个问题的全部目的是禁止该字段的空值。
-
好吧,这更能说明问题。但是为什么你需要知道模型是什么样的?您当前的代码显示您返回模型实例而不是模型类
标签: django django-models django-migrations