根据与 django 多态模型子类的关系过滤普通模型?

Filtering plain models on their relation to a subclass of a django polymorphic model?

我有一个普通的 Django 模型,它与 Django 多态模型具有外键关系。

让我们将具有 content ForeignKey 字段的第一个 PlainModel 调用为具有子类型 VideoAudio 的多态 Content 模型(简化示例) .

现在我想查询所有 PlainModel 个引用 Video 的实例。

问题是我找到的所有文档都是关于直接通过多态模型本身进行过滤的。所以在这个例子中,类似于 Content.objects.instance_of(Video)。但我需要 PlainModel,所以它需要看起来像 PlainModel.objects.filter(content__instance_of=Video)。我尝试了很多变体,但找不到任何有效的方法。

在文档中他们使用 Q(instance_of=ModelB),但这不适用于 Q(content__instance_of=ModelB) 的关系。即使是翻译调用,它也会给出类似 'Cannot query "x": Must be "y" instance.' 的错误,我猜是因为 PlainModel 不支持多态。

我有一个临时 hack,它使用像 PlainModel.objects.filter(content__polymorphic_ctype_id=my_content_type_id) 这样的常规 django 过滤器直接过滤 polymorphic_ctype 字段,但这不处理子类。例如:在查找 Video 时不会找到 ExtendedVideo,因为它具有不同的 ContentType id。

我可以解决这个问题并保留一个允许的子类型列表或解析类型层次结构以获得过滤器的更多内容类型,但这似乎复制了 django-polymorphic 的功能。

您可以先获取所有具有 Video 子类型的 PlainModel 实例,然后查询该查询集中的外键关系:

content_videos = Content.objects.instance_of(Video)
plain_model_videos = PlainModel.objects.filter(content__in=content_videos)

请参考the docs

视频plain_models:

PlainModel.objects.filter(content__video__isnull=False)

其他plain_models,视频除外:

PlainModel.objects.filter(content__video__isnull=True)