Django API遇MultiValueDictKeyError,如何实现产品按类别筛选?
修复Django API的MultiValueDictKeyError并实现按类别筛选产品
问题原因分析
- MultiValueDictKeyError触发点:代码中直接用
self.request.GET['category']获取参数,当请求URL里没有category查询参数时,这种取值方式会直接抛出异常——因为GET字典的[]操作符在键不存在时不会返回默认值,而是报错。 - 分类查询逻辑错误:原代码里
category = models.Product.objects.get(category)完全错误,你要获取的是ProductCategory实例,而非Product,且get()方法需要明确的字段筛选条件(比如id=xxx)。 - 缺少异常处理:即便传入了无效的
category值(比如不存在的ID),代码也没有对应的容错逻辑,会导致额外的异常。
修复步骤及代码修改
1. 安全获取查询参数
用request.GET.get('category')替代直接取值,当参数不存在时会返回None,不会触发MultiValueDictKeyError。
2. 完善筛选逻辑
- 无
category参数时,直接返回全部产品; - 有参数时,先验证参数格式(应为分类ID的整数),再获取对应的
ProductCategory实例; - 用
get_object_or_404处理分类不存在的情况,自动返回404响应。
修改后的视图代码
from django.shortcuts import get_object_or_404 from rest_framework import generics import models import serializers class ProductList(generics.ListCreateAPIView): queryset = models.Product.objects.all() serializer_class = serializers.ProductListSerializer def get_queryset(self): qs = super().get_queryset() category_id = self.request.GET.get('category') # 仅当存在category参数时执行筛选 if category_id: # 获取对应分类,不存在则返回404 category = get_object_or_404(models.ProductCategory, id=category_id) qs = qs.filter(category=category) return qs
3. 前端请求要求
确保React前端发送请求时,在URL中携带category查询参数,示例:
http://127.0.0.1:8000/api/products/?category=1
其中1是目标分类的ID值。
额外优化建议
- 如果需要支持按分类名称筛选,可以调整参数逻辑:用
category_name = self.request.GET.get('category_name'),然后执行qs.filter(category__name=category_name); - 可以引入
django-filter库,借助DRF的过滤类实现更优雅的筛选功能,减少手动处理参数的代码量。
内容的提问来源于stack exchange,提问作者Shital
相关产品推荐
相关产品推荐

