django ContentType匹配查询不存在

new9mtju  于 2023-10-21  发布在  Go
关注(0)|答案(9)|浏览(149)

我最近试图加载一些夹具到我的数据库。当我运行服务器并加载各种页面时,我得到错误:

Caught DoesNotExist while rendering: ContentType matching query does not exist.

我试过运行syncdb,并单独重置每个应用程序,但没有任何运气。我该如何让这个错误消失?

bd1hkmkf

bd1hkmkf1#

如果您查看fixture内部,每个fixture都有三个根字段:PK、fields(该表中第PK项的一组字段)和model,后者包含appname.modelname,ORM从中导出表信息。
Django通过ContentType引擎查找的就是appname.modelname,以确定将数据放入哪个表。
您的朋友至少提供了一个fixture,其中model字段的内容与数据库中的任何实际模型都不匹配。这可能是拼写错误、误解、型号或应用程序名称的更改,或者任何数量的错误。但是fixture并不对应于项目中的任何模型,fixture导入器告诉您这一点,它不能将模型的指定名称与项目ContentType表中的任何名称匹配。
修复可能很简单,只要弄清楚表应该有什么作为ContentType,然后打开fixture并在model:行上进行大量搜索和替换。
编辑:
这是一个长(长!)过期编辑。如果您要使用包含泛型数据或对其他地方的泛型表的引用的dumpdata,您必须(我真的无法强调您必须)学习dumpdata --natural标志。它不是按编号保存contentType信息,而是按名称保存,这使得重新加载数据库变得非常容易,也更不容易出错。

zf2sa74q

zf2sa74q2#

我很惊讶没有人提到fixture是一个从第一个值到最后一个值读取的列表。通常有可能会有一行提到稍后添加的表的主键。
这样的错误(产生这个extact问题)在fixture中看起来像这样:

{"model": "lesson", "fields": {"class": 1}},
{
  "model": "class",
  "pk": 1
}

从上面的例子中你可以看到<Model> matching query query doesn't exist(因为pk=1的类还没有添加,所以不能添加课程)。所以你必须在上课之前添加课程,所以只要在夹具中切换它们就可以了。

snz8szmq

snz8szmq3#

您可以手动检查数据库中的每个ContentType表,或者:

  • 如果表为空,则删除数据库中的模型表,然后重新运行syncdb(仅在开发中)

或者你可以使用Django迁移工具之一:

jvlzgdj9

jvlzgdj94#

在某些情况下,当您的fixture包含对不存在的模型的引用时会导致此错误,原因可能是该模型尚未安装,或者其应用尚未添加到您的fixed_APPS中。不幸的是,Django的错误消息在跟踪这个问题时是非常无用的。
如果你编辑django/db/models/query.py中的Queryset.get方法来输出*args**kwargs,你会得到一个更有用的错误消息,比如:

DeserializationError: Problem installing fixture ... ContentType matching query does not exist. args=() kwargs={'model': u'somenewmodel', 'app_label': u'somenewapp'}

然后,您可以检查此模型/应用程序是否已安装或从fixture中删除这些记录。

gcuhipw9

gcuhipw95#

这就是我在经历了很多考验后所做的。我在组和日志方面遇到了很多麻烦。

  • 在sqllite上,启动服务器,转到admin并删除所有组。然后在shell中键入以下内容:
    python manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission -e admin.Logentry > datadump_3.json
  • settings.py中将设置更改为MySQL
  • python manage.py loaddata datadump_3.json
nlejzf6q

nlejzf6q6#

我发现了这个错误的另一个原因,我想补充一下,以防这对其他人有帮助。对我来说,导致这个问题的原因是我创建了一个具有特定权限的组,然后删除了组中引用的应用程序。
具体来说,我曾一度安装了reversion,并创建了一个名为“站点编辑器”的组,该组允许用户创建、编辑和删除修订。后来我卸载了修订版,但当我运行“dumpdata”命令时,组权限仍然存在:

[
{
    "fields": {
        "name": "Site Editor",
        "permissions": [
            [
                "add_logentry",
                "admin",
                "logentry"
            ],
            [
                "change_logentry",
                "admin",
                "logentry"
            ],
            [
                "delete_logentry",
                "admin",
                "logentry"
            ],
            [
                "add_group",
                "auth",
                "group"
            ],
            [
                "change_group",
                "auth",
                "group"
            ],
            [
                "delete_group",
                "auth",
                "group"
            ],
            [
                "add_revision",
                "reversion",
                "revision"
            ],
            [
                "change_revision",
                "reversion",
                "revision"
            ],
            [
                "delete_revision",
                "reversion",
                "revision"
            ],
            [
                "add_version",
                "reversion",
                "version"
            ],
            [
                "change_version",
                "reversion",
                "version"
            ],
            [
                "delete_version",
                "reversion",
                "version"
            ],
            [
                "add_session",
                "sessions",
                "session"
            ],
            [
                "change_session",
                "sessions",
                "session"
            ],
            [
                "delete_session",
                "sessions",
                "session"
            ],
            [
                "add_site",
                "sites",
                "site"
            ],
            [
                "change_site",
                "sites",
                "site"
            ],
            [
                "delete_site",
                "sites",
                "site"
            ]
        ]
    },
    "model": "auth.group",
    "pk": 2
}]

当我试图运行“loaddata”命令时,我一直遇到这个错误:

django.core.serializers.base.DeserializationError: 
Problem installing fixture '/Users/me/Documents/Sites/project/path/fixtures/configuration.json': 
ContentType matching query does not exist.

我的解决方案是简单地删除fixture本身中对reversion和versions的任何引用,如下所示:

[
{
    "fields": {
        "name": "Site Editor",
        "permissions": [
            [
                "add_logentry",
                "admin",
                "logentry"
            ],
            [
                "change_logentry",
                "admin",
                "logentry"
            ],
            [
                "delete_logentry",
                "admin",
                "logentry"
            ],
            [
                "add_group",
                "auth",
                "group"
            ],
            [
                "change_group",
                "auth",
                "group"
            ],
            [
                "delete_group",
                "auth",
                "group"
            ],
            [
                "add_session",
                "sessions",
                "session"
            ],
            [
                "change_session",
                "sessions",
                "session"
            ],
            [
                "delete_session",
                "sessions",
                "session"
            ],
            [
                "add_site",
                "sites",
                "site"
            ],
            [
                "change_site",
                "sites",
                "site"
            ],
            [
                "delete_site",
                "sites",
                "site"
            ]
        ]
    },
    "model": "auth.group",
    "pk": 2
}]

然后,我可以导入夹具没有问题。

oprakyz7

oprakyz77#

从django 1.7开始,dumpdata选项发生了变化:参见http://polarhome.com:753/doc/python-django-doc/html/topics/serialization.html
所以你有用途:

python manage.py dumpdata --natural-foreign --natural-primary --exclude > my_fixture.json
python manage.py loaddata my_fixture.json

或者,也可以解决根本原因:确保源数据库和目标数据库中的内容类型匹配。我在数据库之间移动数据时遇到了同样的错误,其中db 1仍然有来自应用程序的内容类型,这些应用程序在同一时间被删除。在db2中删除这些应用程序,而这些应用程序从未出现过,导致出现此错误消息。
在这种情况下,在数据库级别编辑db 1中的django_content_type表,并删除django应用程序中不再使用的内容类型。然后再次将数据迁移或复制到db2。
如果在其他表中引用了内容类型,则可能需要先将其删除,或者使用DROP CASCADE命令(有风险!).
注意:在数据库级别进行编辑是一项有风险的业务,因此请确保在参与之前进行备份,并且不要在生产数据库上执行此操作。
根据数据库类型的不同,您需要使用不同的工具进行编辑。

mysql -> [MySQLWorkBench][1]
postgres -> [pgAdmin][2] 
SQLite -> [SQLite Browser][3]
oo7oh9g9

oo7oh9g98#

您最近是否从mysql更改为postgres
当查询contenttypes时,类似于:

entry_content_type = ContentType.objects.get(
    app_label="entries", model="Entry"
)

这失败了,因为在postgres中; app_labelmodel都是小写字段。因此,使用__iexact字段查找将忽略大小写。

entry_content_type = ContentType.objects.get(
    app_label__iexact="entries", model__iexact="Entry"
)
ukdjmx9f

ukdjmx9f9#

上面的答案中提出的很多观点也帮助我找到了正确的解决方案。
这个问题在重建Elasticsearch索引时出现。
最终的问题是FK引用了一个不存在的记录。首先,它是如何到达那里的仍然是一个谜,但是创建由外键引用的记录使进程再次运行。

相关问题