我正在我的应用程序中创建一些动态Django模型,除了迁移系统外,一切似乎都按预期工作。
如果我创建一个动态Django模型并设置managed = False,Django的makemigrations
命令仍会为该新模型生成一个迁移。迁移看起来像这样:
class Migration(migrations.Migration):
dependencies = [
('atom', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='books',
fields=[
],
options={
'db_table': 'books',
'managed': False,
},
bases=(models.Model,),
),
]
如果我没有创建迁移,当我运行python manage.py migrate
时,我会看到以下消息(用可怕的红色字母表示):
Your models have changes that are not yet reflected in a migration, and so won't be applied.
Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.
有没有办法告诉Django 1.7中的迁移系统一起忽略非托管模型?或者模型的Meta类中的migrations = False
设置?
更新:为了澄清,我使用的方法来创建类似于以下地方描述的动态模型:
此方法非常适合根据存储在配置模型(https://code.djangoproject.com/wiki/DynamicModels#Adatabase-drivenapproach)中的信息生成动态模型。我确实必须注册一个信号来清除django模型缓存,以便在更改Configuration实例时捕获对模型的更改,但除了为这些模型生成迁移这一事实外,一切似乎都很好。如果我删除其中一个配置并且模型已从Django的缓存中删除,则需要再次更新迁移,删除它不应该关心的模型。
这些动态模型未在应用程序中专门使用。我没有在代码中的哪个地方引用书籍模型(来自上面的例子)。它们是在运行时生成的,用于从他们提供访问的旧表中读取信息。
答案 0 :(得分:3)
简短的回答是Django不是为此而建的。使您的模型"不受管理" only means Django will not create or delete the table for it -- nothing else
也就是说,如果您在同一个应用中没有这些动态模型的常规模型,您可以有条件地将应用添加到INSTALLED_APPS
中的settings.py
:
if not ('makemigrations' in sys.argv or 'migrate' in sys.argv):
INSTALLED_APPS += (
'app_with_dynamic_models',
'another_app_with_dynamic_models',
)
这应该使Django在创建和运行迁移时忽略该应用程序。但是,如果要使用模型,最终必须为模型制作和运行迁移,因为the ability to have apps which do not use migrations is meant to go away in Django 1.9。您的动态模型是否可以重构为使用contenttypes framework?
答案 1 :(得分:2)
我建议您将自己生成的migrations.CreateModel
操作替换为始终反映实际模型状态的操作。这样就不会检测到状态变化。
class CreateDynamicModel(CreateModel):
def __init__(self):
# ... dynamically generate the name, fields, options and bases
super(CreateDynamicModel, self).super(
name=name, fields=fields, options=optins, bases=bases
)
答案 2 :(得分:1)
您可以使用allow_migrate方法编写自定义数据库路由器,为您的动态模型返回False
。在这种情况下,migrate
命令将禁止它们。
只要您不在任何models.py
模块中加载这些动态模型,makemigrations
就不应该选择它们。