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

使用DjangoFilter过滤SerializerMethodField字段时报错:True不是有效字段

问题原因

你用SerializerMethodField定义的is_favorited是序列化阶段动态计算的字段,不属于Recipe模型的数据库字段,DjangoFilterBackend默认只能基于模型实际存在的字段做过滤,所以直接在filterset_fields里加这个字段会报错。

解决方法

需要自定义FilterSet类,手动实现is_favorited的过滤逻辑,步骤如下:

1. 自定义RecipeFilter类

在你的app下新建或修改filters.py,写入以下代码:

from django_filters import rest_framework as filters
from .models import Recipe, Favorite

class RecipeFilter(filters.FilterSet):
    is_favorited = filters.BooleanFilter(method='filter_is_favorited')

    def filter_is_favorited(self, queryset, name, value):
        user = self.request.user
        # 匿名用户无收藏数据,直接返回空集合
        if user.is_anonymous:
            return queryset.none()
        # 提取当前用户收藏的所有食谱ID
        favorited_ids = Favorite.objects.filter(user=user).values_list('recipe_id', flat=True)
        if value:
            # 过滤出已收藏的食谱
            return queryset.filter(id__in=favorited_ids)
        else:
            # 过滤出未收藏的食谱
            return queryset.exclude(id__in=favorited_ids)

    class Meta:
        model = Recipe
        fields = ['is_favorited']  # 可添加其他需要过滤的模型字段

2. 修改视图集配置

把原来的filterset_fields替换为自定义的filterset_class:

from .filters import RecipeFilter

class RecipeViewSet(viewsets.ModelViewSet):
    queryset = Recipe.objects.all()
    serializer_class = RecipeSerializer  # 替换为你的序列化器类
    filter_backends = [filters.DjangoFilterBackend]
    filterset_class = RecipeFilter  # 指定自定义FilterSet

3. 验证过滤效果

现在在Postman中可以正常使用参数过滤:

  • ?is_favorited=true:返回当前用户已收藏的食谱
  • ?is_favorited=false:返回当前用户未收藏的食谱
  • 匿名用户请求任意is_favorited参数都会返回空集合,和序列化器逻辑一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 10:01:42