【问题标题】:Filtering plain models on their relation to a subclass of a django polymorphic model?根据与 django 多态模型的子类的关系过滤普通模型?
【发布时间】:2017-02-21 10:20:35
【问题描述】:

我有一个普通的 Django 模型,它与 django 多态模型有 ForeignKey 关系。

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

现在我想查询所有引用VideoPlainModel 实例。

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

在他们使用Q(instance_of=ModelB) 的文档中,但这不适用于Q(content__instance_of=ModelB) 的关系。它给出了一个错误,如“无法查询“x”:必须是“y”实例。即使有翻译调用,我猜是因为 PlainModel 不支持多态。

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

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

【问题讨论】:

    标签: python django django-polymorphic


    【解决方案1】:

    视频plain_models:

    PlainModel.objects.filter(content__video__isnull=False)
    

    其他plain_models,视频除外:

    PlainModel.objects.filter(content__video__isnull=True)
    

    【讨论】:

      【解决方案2】:

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

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

      请参考the docs

      【讨论】:

      • 好主意,但我必须查看它执行的 SQL,看看这是否可以接受。 IIRC 有一些关于 __in 子句的查询集。
      • @Bartvds 这不是特定于 Django 多态的,因为我们知道第一个查询会为您提供第二个查询所需的 id。参考文档中的 SQL 查询更新了我的答案。
      • 当然,但我希望有一个使用 JOIN 的解决方案(通过 Django 多态或直接通过 ORM);正如文档所指出的那样,子查询在性能方面并不是那么好,尤其是在像我们这样的大型表中。但我认为我们需要进行基准测试,看看这是否已经可以接受。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-22
      • 2016-11-13
      • 2014-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-02
      相关资源
      最近更新 更多