如何用Tortoise-ORM筛选关联所有指定M2M标识符的对象?
在Tortoise-ORM中筛选同时拥有所有指定关联对象的多对多模型
先说说你之前两种方法失效的原因:
- 用
Custom.filter(properties__id__in=[1,2,3]).distinct()会把只要关联了其中任意一个Property的Custom都捞出来,所以Custom2因为关联了ID1也会被选中,不符合需求。 - 直接用Q组合多个
properties__id条件,比如Q(properties__id=1) & Q(properties__id=2),本质是要求同一条关联记录同时满足多个ID,这显然不可能,所以返回空列表。
给你两种无需后续处理就能直接拿到目标对象的方法:
方法一:用annotate统计匹配数量(推荐,高效)
通过给每个Custom对象添加一个统计字段,计算它关联的Property中匹配目标ID的数量,再筛选数量等于目标ID列表长度的对象——只有同时拥有所有指定Property的Custom,统计数才会和列表长度一致。
代码示例:
from tortoise.expressions import Q, Count target_ids = [1, 2, 3] result = await Custom.annotate( matched_count=Count("properties", filter=Q(properties__id__in=target_ids)) ).filter(matched_count=len(target_ids))
执行后result里就只有Custom1。
方法二:链式叠加filter(直观,代码简洁)
对每个目标ID依次叠加filter,每次筛选都要求Custom存在该ID的关联Property。多次叠加后,只有同时满足所有关联要求的Custom会被保留,最后加distinct()去重(多对多关联查询会产生笛卡尔积,可能返回重复对象)。
代码示例:
target_ids = [1, 2, 3] query = Custom.all() for prop_id in target_ids: query = query.filter(properties__id=prop_id) result = await query.distinct()
这个方法也能精准拿到Custom1。
内容的提问来源于stack exchange,提问作者KusochekDobra
相关产品推荐
相关产品推荐

