如何在Django Rest Framework中更新JSON字段的指定键值?
问题原因
你的代码存在两个核心问题,导致JSON字段被整体替换:
- 视图层逻辑错误:构造
data_to_change时,直接将布尔值赋值给'fruit'键,而非修改原JSON字典的指定键。 - 序列化层更新逻辑缺失:Serializer的
update方法直接用传入值覆盖整个fruit字段,未做字典合并更新。
修复方案
1. 修改views.py,正确构造更新数据
复制原用户的fruit字典,修改指定键的取值后再传入Serializer,避免直接替换整个字段:
from rest_framework import status class UpdateFruitView(generics.UpdateAPIView): queryset = Account.objects.all() serializer_class = FruitSerializer permission_classes = (IsAuthenticated,) def update(self, request, *args, **kwargs): fruit_key = request.data.get("fruit") if not fruit_key: return Response({"error": "请指定要修改的水果名称"}, status=status.HTTP_400_BAD_REQUEST) # 复制原JSON字典,避免直接修改数据库对象属性 updated_fruit = request.user.fruit.copy() # 切换目标键的布尔值 updated_fruit[fruit_key] = not updated_fruit.get(fruit_key, False) serializer = self.serializer_class(request.user, data={'fruit': updated_fruit}, partial=True) if serializer.is_valid(): self.perform_update(serializer) return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
2. 优化serializers.py,支持JSON字段部分更新
如果需要支持前端传入部分字典(如{"fruit": {"Apple": true}})自动合并到原字段,可修改update方法:
class FruitSerializer(serializers.ModelSerializer): class Meta: model = Account fields = ["fruit"] def update(self, instance, validated_data): fruit_data = validated_data.get('fruit') if isinstance(fruit_data, dict): # 合并传入的字典到原JSON字段 instance.fruit.update(fruit_data) else: instance.fruit = fruit_data if fruit_data is not None else instance.fruit instance.save() return instance
3. 请求示例
前端可发送两种格式的请求:
- 直接指定要切换的水果名称:
{"fruit": "Apple"}
- 直接传入目标键的新值:
{"fruit": {"Apple": true}}
验证效果
修改前fruit字段:
{"Apple":false, "Pear": true, "Orange":false}
发送修改Apple的请求后,fruit字段变为:
{"Apple":true, "Pear": true, "Orange":false}
内容的提问来源于stack exchange,提问作者VaclavJirka
相关产品推荐
相关产品推荐

