带有来自相关 table 过滤注释的 Django 查询
django query with filtered annotations from related table
以书籍和作者模型为例,书籍有一位或多位作者。具有 cover_type 的书籍和具有来源国家/地区的作者。
我怎样才能列出所有精装书和作者来自法国的书籍?
Books.objects.filter(cover_type='hard', authors__origin='france')
此查询不检索有精装书但没有法国作者的书籍。
我想要所有精装书,这是谓词 #1。
如果他们的作者来自法国,我希望他们有注释,否则作者字段可能为空或 'None'。
例如。:
`
Bookname, covertype, origin
The Trial, hardcover, none
Madam Bovary, hardcover, France
`
尝试了很多选项,annotate,Q,value,subquery,when,case,exists 但可以想出一个解决方案。
使用 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.id=454523 with buildigtype 其中建筑类型处于活动状态,建筑类型可能是建筑物为空或只有 1 个主动和零个或多个被动)
您应该在 Auther 中使用 Book id table.then 您的查询将是这样的:Author.objects.filter(origin="france",book__cover_type="hard")
我想我用子查询、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')
`
以书籍和作者模型为例,书籍有一位或多位作者。具有 cover_type 的书籍和具有来源国家/地区的作者。
我怎样才能列出所有精装书和作者来自法国的书籍?
Books.objects.filter(cover_type='hard', authors__origin='france')
此查询不检索有精装书但没有法国作者的书籍。
我想要所有精装书,这是谓词 #1。
如果他们的作者来自法国,我希望他们有注释,否则作者字段可能为空或 'None'。
例如。:
`
Bookname, covertype, origin
The Trial, hardcover, none
Madam Bovary, hardcover, France
`
尝试了很多选项,annotate,Q,value,subquery,when,case,exists 但可以想出一个解决方案。
使用 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.id=454523 with buildigtype 其中建筑类型处于活动状态,建筑类型可能是建筑物为空或只有 1 个主动和零个或多个被动)
您应该在 Auther 中使用 Book id table.then 您的查询将是这样的:Author.objects.filter(origin="france",book__cover_type="hard")
我想我用子查询、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')
`