DJangon数据库已经生成数据表,已经设置"created_at"字段,如何实现(生成、修改)时间信息更迭。

一问题:
原来后端数据库只有 created_at字段 没有update_at字段
二:解决思路及方法:

现状

数据库现有字段:created_at(创建时间,auto_now_add),没有 update_at
需要实现:小程序修改提交 PATCH,后端自动生成更新时间存入数据库。

步骤1:models.py 添加 update_at 字段

from django.db import models

class Preregistration(models.Model):
    username = models.CharField(max_length=100)
    IDnumber = models.CharField(max_length=20)
    phone = models.CharField(max_length=20)
    email = models.CharField(max_length=100)
    depart = models.IntegerField()
    relation = models.IntegerField()
    is_delete = models.BooleanField(default=False)

    created_at = models.DateTimeField(auto_now_add=True)
    # 新增更新时间字段
    update_at = models.DateTimeField(auto_now=True, null=True, blank=True)

null=True:旧历史老数据,第一次迁移允许该字段为null;后续每次修改自动填充时间。
auto_now=True每次 save() 自动赋值当前时间,前端完全不用传

步骤2:执行数据库迁移

python manage.py makemigrations
python manage.py migrate

执行完数据库表就多出 update_at 列。

步骤3:serializers.py 设置只读,禁止前端传入

class PreregSerializer(serializers.ModelSerializer):
    class Meta:
        model = Preregistration
        fields = ["id", "username", "IDnumber", "phone", "email", "depart", "relation", "created_at", "update_at"]
        read_only_fields = ["id", "created_at", "update_at"]

read_only_fields

  • 返回给小程序接口响应可以看到 update_at
  • 小程序发过来的请求里就算带上 update_at,直接忽略,不会生效,只能后端自动生成。

步骤4:patch视图不用做任何改动

def patch(self,request,pk):
    try:
        item = Preregistration.objects.get(id=pk)
    except ObjectDoesNotExist:
        return Response({"code":404,"msg":"记录不存在"}, status=404)

    serializer = PreregSerializer(instance=item, data=request.data , partial=True)
    if serializer.is_valid():
        serializer.save()  # ✔ auto_now自动给update_at赋值,不需要手动写代码
        return Response({'code':200,'msg':'Success','result':serializer.data})
    
    print("打印错误:",serializer.errors)
    return Response({'code':400,'msg':'Error','error':serializer.errors}, status=400)

只要执行 serializer.save(),无论哪些字段修改,update_at 自动刷新。

步骤5:小程序前端过滤,不要提交时间字段

js提交submitData过滤掉id、created_at、update_at、is_delete

let submitData = {}
Object.keys(this.data.editItem).forEach(key=>{
  const val = this.data.editItem[key]
  // 过滤主键、时间、删除标记,不传给后端
  if(key === 'id' || key === 'created_at' || key === 'update_at' || key === 'is_delete'){
    return;
  }

  if(typeof val === 'number'){
    submitData[key] = val
  }else{
    const strVal = val == null ? "" : String(val)
    const trimVal = strVal.trim()
    if(trimVal !== ""){
      submitData[key] = strVal
    }
  }
})

针对老数据说明

旧的数据库历史数据:

  • 刚迁移完成,老记录的update_atnull
  • 只要这条记录被修改一次,执行PATCH保存,auto_now就会自动填上时间

如果你希望迁移时把老数据的update_at直接等于created_at,可以写迁移脚本,一般业务不需要,修改的时候自动填充就够用。


备选方案:不想新增数据库字段(不推荐)

不建update_at,就无法持久保存修改时间,只能靠接口返回当前服务器时间,数据库不会留存,业务几乎不用,优先上面加字段方案。

验证效果

小程序编辑提交PATCH,查看数据库:
created_at保持创建时时间不变;
update_at变成本次PATCH接口调用的服务器时间。

posted @ 2026-08-16 12:14  ham0921  阅读(2)  评论(0)    收藏  举报