为什么 Django 会为代理模型创建迁移文件?

Why does Django create migration files for proxy models?

我刚刚创建了一个 proxy model,令我惊讶的是 manage.py makemigrations 使用 migrations.CreateModel 操作创建了一个新的迁移文件。

代理模型不会创建新数据库 table,它只是同一数据集的不同 python 接口,实际上 manage.py sqlmigrate my_app_label 0042 returns 什么都没有。

我认为它可能用于创建代理模型 ContentType 但如果它们不存在,则按需创建。

是否用于触发创建代理模型权限?代理模型权限有一个 6 year old open bug,所以我不太确定这部分现在应该如何工作...

它使用 Django 1.8 来测试它。

编辑:澄清一下,Django 创建了一个对新代理模型没有任何作用的迁移,所以我们不希望 Django 不创建没用就先迁移?

是否有迁移有用的用例?

啊,但是如果你在你的编辑器中打开迁移,你会发现它实际上是一个空的迁移!这是一个例子

class Migration(migrations.Migration):
    dependencies = [
        ('Whosebug', '0009_auto_20160622_1507'),
    ]

    operations = [
        migrations.CreateModel(
            name='MyArticle',
            fields=[
            ],
            options={
                'proxy': True,
            },
            bases=('Whosebug.article',),
        ),
    ]

如果你 运行 ./manage.py sqlmigrate myapp 0010(这是对应于我上面的迁移的数字),你得到的是下一行的内容(什么都没有)。

这是因为迁移的 fields 部分是空的,而 option 包括 proxy = True。此设置可防止为此迁移执行任何 SQL,并且原始 table 保持不变。

所以您可能会问,为什么 Django 费心创建一个空迁移?这是因为在未来的迁移中,代理模型可能会被另一个模型引用。

我相信 migrations 是因为数据库受到影响而生成的,migrations 是 Django 发出数据库更改信号的方式。结构没有改变,但在(至少)两个表中添加了条目:

  • 代理模型的 django_content_type 添加了一个新的 ContentType
  • 特定于代理模型的权限已添加到 auth_permission。我假设这种 "always" 会发生,除非代理使用完全相同的 class 名称。它确实发生了——我们实际上使用代理模型来访问使用不同权限的用户,而无需触及默认用户模型。

这两个细节实际上都记录在 OP 链接的问题的评论链中(例如评论 #31),因为它们导致了错误(即 Django 在与实际生成的应用程序不同的应用程序中查找权限在 auth_permissions).