如何通过中间模型查询Django中指定Post的关联Category?
Django自定义多对多中间表的分类查询问题
模型定义
class Post(models.Model): ... class Category(models.Model): ... class PostCategory(models.Model): """因其他需求限制,无法直接使用ParentalManyToMany字段,需用此关联类""" post = ParentalKey( 'models.Post', on_delete=models.CASCADE, related_name='categories', ) category = models.ForeignKey( 'models.Category', on_delete=models.CASCADE, related_name='posts', ) class Meta: unique_together = ('post', 'category')
问题场景
已筛选出Post查询集 posts = Post.objects.filter(...),需要获取这些Post关联的所有去重Category:
- 直接执行
Category.objects.filter(post__in=posts)报错:ValueError: Cannot query 'posts': Must be "PostCategory" instance. - 执行
PostCategory.objects.filter(post__in=posts)得到的是PostCategory实例,需要从中提取去重的Category
解决方案
方案1:直接查询Category(推荐)
利用Category的posts关联(对应PostCategory实例),通过中间表的post字段关联到目标Post集合,最后用distinct()去重:
categories = Category.objects.filter(posts__post__in=posts).distinct()
解释:posts__post表示先通过Category关联的PostCategory实例(posts),再取其中的post字段关联到Post模型,这样就能正确匹配筛选后的Post集合,distinct()避免同一个Category被多次返回。
方案2:从PostCategory查询集提取Category
先获取关联的Category ID,再查询Category:
# 第一步:获取去重的Category ID集合 category_ids = PostCategory.objects.filter(post__in=posts).values_list('category_id', flat=True).distinct() # 第二步:通过ID查询Category categories = Category.objects.filter(id__in=category_ids)
或者合并为单条查询(性能相近):
categories = Category.objects.filter( id__in=PostCategory.objects.filter(post__in=posts).values('category_id') ).distinct()
内容的提问来源于stack exchange,提问作者Konstantin
相关产品推荐
相关产品推荐

