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

基于Django Rest Framework的模型数据更新实现咨询

嘿,我帮你看看这段DRF的update代码,这里确实有几个关键问题,咱们一步步捋清楚:

现有代码的核心问题
  • 根本不是更新操作,而是新建数据:你初始化InfoSerializer时只传了data=data,没有传入要更新的instance实例。DRF序列化器的规则是:不带instance时,save()会执行create()方法创建新对象;只有传入目标instance,才会执行update()方法修改现有数据。所以你现在的代码每次调用更新接口都会新增一条Info记录,完全达不到更新现有数据的目的。
  • 浪费了ModelViewSet的内置逻辑:父类ModelViewSet已经帮你实现了获取目标实例、权限校验、处理部分更新(PATCH请求)等逻辑,你重写后完全绕开了这些成熟的实现,反而要自己处理很多边缘情况(比如实例不存在的404异常)。
  • 返回格式不符合DRF规范:你用了原生的JsonResponse,但DRF提供的Response类能自动处理内容协商(比如根据请求头返回不同格式)、正确设置状态码,比原生响应更适配框架生态。
  • 冗余配置:lookup_field = 'id'是DRF的默认值,完全可以省略不写,不会影响功能。
优化后的实现方案

分两种情况来处理,根据你的需求选择:

情况1:无特殊自定义需求(推荐)

如果只是需要标准的更新逻辑,完全不需要重写update方法,ModelViewSet已经内置了完整的CRUD操作,直接用默认实现即可:

class InfoViews(viewsets.ModelViewSet):
    queryset = Info.objects.all()
    serializer_class = InfoSerializer
    # lookup_field = 'id'  # 可省略,默认就是id

情况2:需要自定义更新逻辑(比如更新前后加额外操作)

如果要在更新前后加自定义逻辑(比如记录操作日志、修改关联字段),正确的重写方式应该复用父类的核心逻辑:

from rest_framework.response import Response

class InfoViews(viewsets.ModelViewSet):
    queryset = Info.objects.all()
    serializer_class = InfoSerializer

    def update(self, request, *args, **kwargs):
        # 1. 利用父类方法获取要更新的目标实例(自动处理404异常)
        instance = self.get_object()
        # 2. 初始化序列化器:传入instance+data,同时支持部分更新(兼容PATCH请求)
        serializer = self.get_serializer(
            instance, 
            data=request.data, 
            partial=kwargs.get('partial', False)
        )
        serializer.is_valid(raise_exception=True)
        
        # --- 这里加你的自定义逻辑,比如更新前校验或日志记录 ---
        # example: record_update_log(instance, request.user)
        
        # 3. 执行更新(复用父类的perform_update,兼容信号等钩子)
        self.perform_update(serializer)
        
        # --- 这里加更新后的自定义逻辑 ---
        # example: sync_related_data(instance)
        
        return Response(serializer.data)
额外注意点

确保你的InfoSerializer是正确的ModelSerializer实现,比如:

from rest_framework import serializers
from .models import Info

class InfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Info
        fields = '__all__'  # 或指定需要序列化的字段

如果需要自定义字段更新逻辑,再在InfoSerializer里重写update方法即可,不用在视图层处理。

内容的提问来源于stack exchange,提问作者user9341676

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:16:23