You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()

补充说明

  1. 旧版本正常的原因:Django 3.1及更早版本中,多对多字段的__in查询默认是OR逻辑,4.2版本调整为更严格的AND逻辑(对应SQL中的EXISTS子句叠加),这是官方明确的行为变更。
  2. 无需更换graphene-django版本,只要用上述自定义过滤器方法,就能完全还原旧版本的查询逻辑。

内容的提问来源于stack exchange,提问作者Jolly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 16:43:31