Django 后台在记录保存时先保存旧记录内容

发布于 2024-06-13 12:28:45 字数 4239 浏览 20 评论 0

场景:在一些重要的数据表,如设备台账表里,我们希望在记录保存时能够先保存一下旧记录内容,以便出现错误修改时能反查,恢复,这就是我们的需求。

首先我们考虑一下,各数据表数据结构各不相同,如果针对每一个数据表做一个备份表太过繁琐,所以我们考虑只用一个 TextField 来保存旧记录内容,而把记录的各字段内容生成 Json 的形式保存到 TextField 中,就可以不用管各数据表的字段有多少,再附上方便检索和引用的表名、记录号、修改时间、操作人员等字段信息,那一个备份表就基本上够了。

我们在 recordbackup 这个应用里

# recordbackup.models.py
from django.db import models

# Create your models here.

class RecordBack(models.Model):
app = models.CharField(max_length=20, verbose_name='应用', blank=True)
model = models.CharField(max_length=20, verbose_name='数据表')
rid = models.IntegerField(verbose_name='记录号')
content = models.TextField(verbose_name='原记录内容')
modified_time = models.DateTimeField(verbose_name='修改时间')
user = models.CharField(max_length=20, verbose_name='操作人')

class Meta:
verbose_name_plural = verbose_name = '记录备份'

创建 admin.py 用于后台查看备份数据,只读

# recordbackup/admin.py
from django.contrib import admin
from .models import *

# Register your models here.

@admin.register(RecordBack)
class RecordBackAdmin(admin.ModelAdmin):
list_display = ('app', 'model', 'rid', 'modified_time', 'user', 'list_operate')
readonly_fields = ('app', 'model', 'rid', 'content', 'modified_time', 'user')
list_filter = ('app', 'model',)

def list_operate(self, obj):
return '<a href="/admin/%s/%s/%s/"><i class="icon-th-list" title="查看原记录"></i></a>' % (obj.app, obj.model, obj.rid)
list_operate.short_description = '操作'
list_operate.allow_tags = True

生成相关数据表

./manage.py makemigrations
./manage.py migrate

再创建一个 utils.py 用于转换记录为 Json 和保存旧记录功能的函数。

# recordbackup/utils.py
import json
import datetime

def toJSON(obj):
"""
对对象进行 json 序列化,以 json 序列方式保存记录内容
:param obj: 记录对象
:return: 返回 json 串
"""
fields = []
for field in obj._meta.fields:
fields.append(field.name)

d = {}
for attr in fields:
if isinstance(getattr(obj, attr),datetime.datetime):
d[attr] = getattr(obj, attr).strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(getattr(obj, attr),datetime.date):
d[attr] = getattr(obj, attr).strftime('%Y-%m-%d')
else:
d[attr] = getattr(obj, attr)
return json.dumps(d)

def OldRecordSave(self, request, obj, form, change):
"""
保存旧记录的数据
:param self: 修改前的记录对象
:param request:
:param obj: 修改后的记录对象
:param form: 表单数据
:param change: 表单数据是否被修改
:return: None
"""
from .models import RecordBack
if change:# 更改的时候
rb = RecordBack()
rb.app = self.model._meta.app_label
rb.model = self.model.__name__.lower()
rb.rid = obj.pk
rb.modified_time = datetime.datetime.now()
obj_original = self.model.objects.get(pk=obj.pk)
if obj_original:
rb.content = toJSON(obj_original)
rb.user = request.user
rb.save()
else:# 新增的时候
pass

现在记录备份的功能可以用了,我们在台账数据表 PcAdminsave_model() 里加了保存旧记录的操作 OldRecordSave()

# pc/admin.py
from .models import *
from recordbackup.utils import OldRecordSave
class PcAdmin(admin.ModelAdmin):
......
def save_model(self, request, obj, form, change):
OldRecordSave(self, request, obj, form, change) # 保存旧记录的数据到备份表
obj.save()

现在我们可以做一个测试,进入 PC 的编辑页面,修改一个字段信息,然后保存,我们看看 记录备份 表是不是多出一条记录,内容正是 PC 保存前的内容。
类似的,我们只要在需要保存旧数据的 admin 中引入 from recordbackup.utils import OldRecordSave ,再在 save_model()obj.save() 前加入 OldRecordSave(self, request, obj, form, change) 就可以实现旧记录数据的保存了。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

孤单情人

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

謌踐踏愛綪

文章 0 评论 0

开始看清了

文章 0 评论 0

高速公鹿

文章 0 评论 0

alipaysp_PLnULTzf66

文章 0 评论 0

热情消退

文章 0 评论 0

白色月光

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文