python - 使用子对象字段过滤查询集
问题描述
我有两个模型父,子
class Parent(models.Model):
id = models.IntegerField(...)
class Child(models.Model)
id = models.IntegerField(...)
parent = models.ForeignKey(Parent, ...)
wanted = models.CharField(default="yes")
我想过滤所有与该父母一起出现的孩子将“想要”为“是”的所有父母对象
我的代码:
def containsYes(self):
yes_ids = []
qs = self.get_queryset()
for q in qs:
children = Child.objects.filter(parent_id = q.id)
count = children .count()
if children.filter(wanted = 'yes').count() == count
yes_ids.append(q.id)
return qs.filter(id__contains = yes_ids)
我知道这段代码效率很低,并且想要一个只使用查询的更好的解决方案
PS:我是 Django 新手
解决方案
我们可以排除Parent
存在不想要的孩子的 s,因此我们可以使用:
from django.db.models import F, Count, Q
Parent.objects.annotate(
nchild=Count('child')
nchild_wanted=Count('child', filter=Q(child__wanted=True))
).filter(
nchild=F('nchild_wanted')
)
因此,我们首先计算相关Child
s 的数量,并将相关Child
s的数量wanted
设置为True
。然后我们过滤并只保留Parent
这两个注释相同的对象。
从django-3.2开始,可以使用.alias(…)
[Django-doc]来防止在SELECT
子句和HAVING
子句中计数:
from django.db.models import F, Count, Q
Parent.objects.alias(
nchild=Count('child')
nchild_wanted=Count('child', filter=Q(child__wanted=True))
).filter(
nchild=F('nchild_wanted')
)
推荐阅读
- java - 如何在使用 java 库创建 excel (xls) 文件时锁定单元格
- python - 我在 Flask 中的身份验证功能,始终允许用户进入受限页面
- java - 在java中创建parquet文件而不保存在磁盘上
- css - 如何编辑 css ::after 元素?
- visual-studio-code - vscode在下拉菜单/快速打开菜单中使用选项卡和移位选项卡进行上下移动
- java - 在没有方法体的情况下在 Eclipse 中导出 JAR 文件
- ansible - Ansible 调试 INI 格式
- python - 如何理解联合图中的 p 值?
- python-3.x - Drf令牌认证密码重置
- alexa - 由于无效正文 ASK CLI 导致解析错误