Django 4.2与graphene-django过滤器查询返回空结果求助
解决Django 4.2 + graphene-django中多对多字段__in查询返回空结果的问题
问题根源是Django 4.2对多对多字段的__in查询逻辑做了变更——旧版本里users__email__in会自动用OR逻辑匹配任意一个邮箱,而新版本默认采用AND逻辑,要求记录同时匹配所有传入的邮箱值,这直接导致了空结果。
直接给你可行的解决方法:自定义过滤器方法,手动用Q对象构建OR条件,替代默认的__in处理逻辑:
from django.db.models import Q from django_filters import FilterSet, StringInFilter class ExampleFilterSet(FilterSet): label__name__in = StringInFilter(method="filter_labels") # 自定义users__email__in过滤器,替换默认行为 users__email__in = StringInFilter(method="filter_users_email_in") class Meta: model = Example fields = [] # 移除原fields中对users__email的定义,改用自定义过滤器 def filter_users_email_in(self, queryset, name, value): # 构建OR条件,匹配列表中任意一个邮箱 query_condition = Q() for email in value: query_condition |= Q(users__email=email) # 用distinct避免多对多关联导致的重复结果 return queryset.filter(query_condition).distinct() def filter_labels(self, queryset, name, value): # 给label的in查询也统一用OR逻辑 query_condition = Q() for label_name in value: query_condition |= Q(label__name=label_name) return queryset.filter(query_condition).distinct()
补充说明
- 旧版本正常的原因:Django 3.1及更早版本中,多对多字段的
__in查询默认是OR逻辑,4.2版本调整为更严格的AND逻辑(对应SQL中的EXISTS子句叠加),这是官方明确的行为变更。 - 无需更换graphene-django版本,只要用上述自定义过滤器方法,就能完全还原旧版本的查询逻辑。
内容的提问来源于stack exchange,提问作者Jolly
相关产品推荐
相关产品推荐

