DRF中同一端点实现多序列化器的查询与更新问题
解决DRF同一端点支持查询与更新并输出组合JSON的问题
1. 修正组合序列化器
你的SupplyDetail_Serializer存在两处问题:数组类型字段未声明many=True,以及new_supplies错误引用了Current_supplies_Serializer,修正后代码如下:
class SupplyDetail_Serializer(serializers.Serializer): meter_detail = Meter_Detail_Serialzer() current_supplies = Current_supplies_Serializer(many=True) new_supplies = New_supplies_Serializer(many=True) # 修正为对应模型的序列化器
2. 替换视图基类并实现业务逻辑
原ListAPIView仅支持列表查询,无法满足单对象的查询(retrieve)和更新(update)需求,改用RetrieveUpdateAPIView作为基类,手动组装、处理三个模型的数据:
from rest_framework.generics import RetrieveUpdateAPIView from rest_framework.response import Response from .models import Meter_detail, Current_supplies, New_supplies from .serializers import ( Meter_Detail_Serialzer, Current_supplies_Serializer, New_supplies_Serializer, SupplyDetail_Serializer ) class SupplyDetailView(RetrieveUpdateAPIView): queryset = Meter_detail.objects.all() def get(self, request, *args, **kwargs): # 获取指定pk的Meter_detail实例 meter_obj = self.get_object() # 根据关联关系获取对应数据(请替换为你的实际外键字段,比如meter) current_supplies = Current_supplies.objects.filter(meter=meter_obj) new_supplies = New_supplies.objects.filter(meter=meter_obj) # 组装序列化所需数据 context_data = { "meter_detail": meter_obj, "current_supplies": current_supplies, "new_supplies": new_supplies } serializer = SupplyDetail_Serializer(context_data) return Response(serializer.data) def put(self, request, *args, **kwargs): meter_obj = self.get_object() # 拆分请求中的各部分数据 meter_data = request.data.get("meter_detail", {}) current_supplies_data = request.data.get("current_supplies", []) new_supplies_data = request.data.get("new_supplies", []) # 更新Meter_detail(partial=True支持部分字段更新) meter_serializer = Meter_Detail_Serialzer(meter_obj, data=meter_data, partial=True) if not meter_serializer.is_valid(): return Response(meter_serializer.errors, status=400) meter_serializer.save() # 批量更新/新增Current_supplies for item_data in current_supplies_data: item_id = item_data.get("id") try: # 更新已有记录 item = Current_supplies.objects.get(id=item_id, meter=meter_obj) serializer = Current_supplies_Serializer(item, data=item_data, partial=True) except Current_supplies.DoesNotExist: # 新增记录(自动关联当前meter) serializer = Current_supplies_Serializer(data={**item_data, "meter": meter_obj.id}) if not serializer.is_valid(): return Response(serializer.errors, status=400) serializer.save() # 批量更新/新增New_supplies,逻辑同上 for item_data in new_supplies_data: item_id = item_data.get("id") try: item = New_supplies.objects.get(id=item_id, meter=meter_obj) serializer = New_supplies_Serializer(item, data=item_data, partial=True) except New_supplies.DoesNotExist: serializer = New_supplies_Serializer(data={**item_data, "meter": meter_obj.id}) if not serializer.is_valid(): return Response(serializer.errors, status=400) serializer.save() # 更新完成后返回最新数据 return self.get(request, *args, **kwargs)
3. 配置路由
确保路由指向该视图,支持通过pk访问:
from django.urls import path from .views import SupplyDetailView urlpatterns = [ path("supply-detail/<int:pk>/", SupplyDetailView.as_view(), name="supply-detail"), ]
关键说明
- 关联字段替换:代码中假设
Current_supplies和New_supplies通过meter外键关联Meter_detail,请根据你的实际模型字段名修改。 - 部分更新:使用
partial=True允许只更新部分字段,若需要强制更新所有字段可移除该参数。 - 批量处理:更新逻辑支持同时处理已有记录的修改和新记录的添加,若不需要新增功能可删除对应分支。
内容的提问来源于stack exchange,提问作者amit patel
相关产品推荐
相关产品推荐

