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_at是null; - 只要这条记录被修改一次,执行PATCH保存,auto_now就会自动填上时间。
如果你希望迁移时把老数据的update_at直接等于created_at,可以写迁移脚本,一般业务不需要,修改的时候自动填充就够用。
备选方案:不想新增数据库字段(不推荐)
不建update_at,就无法持久保存修改时间,只能靠接口返回当前服务器时间,数据库不会留存,业务几乎不用,优先上面加字段方案。
验证效果
小程序编辑提交PATCH,查看数据库:
created_at保持创建时时间不变;
update_at变成本次PATCH接口调用的服务器时间。
浙公网安备 33010602011771号