Django序列化器动态访问模型字段报错:KeyError: 'request'
解决Django序列化器动态字段的KeyError问题
错误原因
创建ProductTestSerializer实例时,未将请求对象request传入序列化器的context字典,导致序列化器初始化时无法从self.context中获取'request'键,触发KeyError。
修复步骤
1. 在APIView中传递request到序列化器context
修改ProductTestAPIView的get方法,创建序列化器时显式传入context参数:
class ProductTestAPIView(generics.ListAPIView): def get(self, request): obj = Product.objects.all() # 传入context,将request传递给序列化器 data = ProductTestSerializer(obj, many=True, context={'request': request}) s_data = data.data return Response(s_data)
2. 优化序列化器的容错逻辑
为避免后续因context无request导致报错,在DynamicFieldsModelSerializer的__init__方法中增加安全判断:
class DynamicFieldsModelSerializer(serializers.ModelSerializer): def __init__(self, *args, **kwargs): super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs) # 用get方法安全获取request,避免直接取键触发KeyError request = self.context.get('request') if request: fields = request.query_params.get('fields') if fields: fields = fields.split(',') allowed = set(fields) existing = set(self.fields.keys()) for field_name in existing - allowed: self.fields.pop(field_name)
3. 简化序列化器继承关系并补充默认字段
ProductTestSerializer无需重复继承serializers.ModelSerializer(父类已包含),同时要把所有可能被请求的字段加入默认fields列表:
class ProductTestSerializer(DynamicFieldsModelSerializer): class Meta: model = Product fields = ("id", "short_code") # 必须包含所有可能被前端指定的字段,否则无法被筛选返回
注意:默认字段集合必须覆盖前端可能请求的字段,否则即使前端指定了某个字段,序列化器的
self.fields中也不存在该字段,无法保留返回。
测试验证
重新请求目标URL:
http://127.0.0.1:8000/products-test/?fields=id,short_code
此时序列化器会正确读取fields参数,仅返回指定的字段。
内容的提问来源于stack exchange,提问作者Rahul Sharma
相关产品推荐
相关产品推荐

