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

如何在Django及DRF中实现PUT/update动作时自动更新updated_time字段?

解答你的两个Django/DRF相关问题

问题1:查找Django models.py中的HTTP动作

首先得澄清一下:Django的models.py是用来定义数据库模型的,本身并不直接包含HTTP动作。HTTP动作(比如GET、POST、PUT、DELETE这类)是在视图(Views)、视图集(ViewSets)或者路由配置里处理的,这些组件会把HTTP请求和模型的操作(比如创建、更新、删除实例)关联起来。

如果你想找到和某个模型关联的HTTP动作,通常可以这么做:

  • 查看项目的views.py(或者DRF的ViewSet文件):比如DRF的ModelViewSet默认提供了和模型对应的CRUD动作,对应关系是:
    • list → GET(获取模型实例列表)
    • retrieve → GET(获取单个模型实例)
    • create → POST(创建新实例)
    • update → PUT(全量更新实例)
    • partial_update → PATCH(部分更新实例)
    • destroy → DELETE(删除实例)
  • 查看urls.py:路由会把特定的URL路径映射到对应的视图/视图集动作,从中你能看到哪些HTTP方法被绑定到了模型操作上。

举个例子,如果你的Pet模型用了ModelViewSet,视图代码可能是这样的:

from rest_framework import viewsets
from .models import Pet
from .serializers import PetSerializer

class PetViewSet(viewsets.ModelViewSet):
    queryset = Pet.objects.all()
    serializer_class = PetSerializer

这个ViewSet默认就绑定了所有CRUD对应的HTTP动作,你可以在路由里用router.register(r'pets', PetViewSet)来注册,这样就能通过对应的HTTP方法操作Pet模型了。


问题2:PUT/update动作时自动更新updated_time字段

针对你的Pet模型,要实现当执行PUT请求(对应DRF的update动作)时自动更新updated_time,有几种简洁的实现方式,推荐两种最常用的:

方法1:重写DRF序列化器的update方法

这是最直接的方式,因为序列化器负责处理请求数据和模型实例的交互:

from rest_framework import serializers
from .models import Pet
from datetime import datetime

class PetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Pet
        fields = ['kind', 'updated_time']

    def update(self, instance, validated_data):
        # 不管请求里有没有传updated_time,都强制更新为当前时间
        instance.updated_time = datetime.now()
        # 处理其他字段的更新
        instance.kind = validated_data.get('kind', instance.kind)
        instance.save()
        return instance

这样每次调用序列化器的update方法(也就是处理PUT/PATCH请求时),都会自动把updated_time设为当前时间。

方法2:使用Django信号

如果希望在模型实例被更新时(不管是通过API还是后台管理)都自动更新时间,信号是更通用的方案:

from django.db.models.signals import pre_save
from django.dispatch import receiver
from .models import Pet
from datetime import datetime

@receiver(pre_save, sender=Pet)
def update_updated_time(sender, instance, **kwargs):
    # 只在实例已经存在(即更新操作,不是创建)时更新时间
    if instance.pk is not None:
        instance.updated_time = datetime.now()

然后记得在apps.py里注册信号(或者在models.py末尾加pre_save.connect(update_updated_time, sender=Pet)),这样每次更新Pet实例(包括API的PUT动作)都会触发这个信号,自动更新时间。

额外优化:用auto_now字段参数?

哦对了,Django模型字段有个auto_now参数,如果你希望**每次保存实例(包括创建和更新)**都自动更新时间,可以直接这么定义字段:

updated_time = models.DateTimeField(auto_now=True)

但如果你的需求是只在更新(PUT/update动作)时更新,创建时不自动设置,那上面两种方法更合适,因为auto_now=True会在创建实例时也设置时间。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 12:07:33