【问题标题】:django query with filtered annotations from related table带有来自相关表的过滤注释的 django 查询
【发布时间】:2022-01-14 05:12:20
【问题描述】:

以书籍和作者模型为例,书籍拥有一位或多位作者。具有cover_type 的书籍和以国家为原籍的作者。

如何列出所有精装书籍,以及作者来自法国的情况?

Books.objects.filter(cover_type='hard', authors__origin='france') 此查询不检索精装但没有法国作者的书籍。

我想要所有精装书,这是谓词#1。 如果他们的作者来自法国,我希望他们注释,否则作者字段可能为空或“无”。 例如。: `

Bookname,     covertype, origin
The Trial,    hardcover, none
Madam Bovary, hardcover, France

`

尝试了许多选项,注释、Q、值、子查询、何时、案例、存在但可以提出解决方案。

使用 sql 就这么简单:

select * from books b left join authors a on a.bookref=b.id and a.origin=france where b.covertype='hard' (我的模型不是书籍和作者,我选择它们是因为它们是 django-docs 的示例模型。我的模型是 building 和 buildingtype,我想要 building.id=454523 和 buildigtype,其中 buildingtype 处于活动状态,buildingtype 可能为 null建筑物或只有 1 个主动和零个或多个被动)

【问题讨论】:

    标签: django orm left-join


    【解决方案1】:

    您应该在 Auther 表中使用 Book id。那么您的查询将是这样的:Author.objects.filter(origin="france",book__cover_type="hard")

    【讨论】:

    • 相同的查询。这不会带来德国作者的精装书。
    • 为此您可以使用查询:Auther.objects.filter(origin="germany").exclude(book__cover_type="hard")
    • 有趣的是,我认为应该为每个国家/地区编写不同的查询。还是谢谢你。
    【解决方案2】:

    我想我用子查询、outerref、exists、case、when、charfield 解决了它......对于一个简单的 sql,导入太多了。 `

    author = Authors.objects.filter(bookref=OuterRef('id'), origin='France').values('origin')
    
    books = Books.objects.filter(cover_type='hard').annotate(author=Case(When(Exists(author), then=Subquery(author)), default='none', output_field=CharField())).distinct().values('name','cover_type','author')
    

    `

    【讨论】:

      猜你喜欢
      • 2013-05-02
      • 1970-01-01
      • 1970-01-01
      • 2012-04-05
      • 2020-05-14
      • 1970-01-01
      • 2021-12-20
      • 2018-12-08
      • 2011-06-04
      相关资源
      最近更新 更多