You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 09:33:17