DRF中ManyToMany字段显示Null且分页报错:'list'无split属性
问题排查与解决方案
1. category字段显示为Null的问题
原因
在PostSerializer的to_representation方法中,你直接将instance.category(多对多关系返回的QuerySet对象)传给CategorySerializer,但未指定many=True参数。Serializer默认仅处理单个实例,面对QuerySet时无法正确序列化,最终返回Null。
修复代码
修改serializers.py中to_representation方法里的CategorySerializer调用:
representation["category"] = CategorySerializer( instance.category.all(), # 明确获取完整的多对多关联QuerySet many=True, # 关键:指定序列化多个实例 context={"request": request} ).data
2. 分页时抛出AttributeError的问题
原因
错误来自django-filter的value_from_datadict方法,根源是你在PostModelViewSet的filterset_fields中,给多对多字段category配置了["exact", "in"]过滤条件,但django-filter默认组件不支持直接对多对多字段使用in操作,解析参数时会把列表当成字符串处理,导致调用split方法失败。
修复方案
方案一:自定义FilterSet(推荐)
创建filters.py文件,为Post定义专属FilterSet,指定category字段的多对多过滤器:
from django_filters import rest_framework as filters from ...models import Post, Category class PostFilter(filters.FilterSet): category = filters.ModelMultipleChoiceFilter( queryset=Category.objects.all(), field_name="category", lookup_expr="in" ) class Meta: model = Post fields = ["author", "ok_to_publish"] # 保留其他需要过滤的字段
修改views.py中的PostModelViewSet,替换filterset_fields为自定义的filterset_class:
from .filters import PostFilter class PostModelViewSet(viewsets.ModelViewSet): # ... 其他代码不变 filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_class = PostFilter # 替换原filterset_fields配置
方案二:简化过滤配置(快速临时修复)
如果不需要in过滤,可修改filterset_fields移除category的相关配置:
filterset_fields = { "author": ["exact"], "ok_to_publish": ["exact"], }
额外验证
确保你的DefaultPagination类实现正确,示例如下:
from rest_framework.pagination import PageNumberPagination class DefaultPagination(PageNumberPagination): page_size = 10 page_size_query_param = 'page_size' max_page_size = 100
内容的提问来源于stack exchange,提问作者Milad Sadeghi.DM
相关产品推荐
相关产品推荐

