Django Admin的版本管理和回滚
Django Admin默认提供了版本管理功能,可以方便地在后台管理界面进行记录和比较不同版本的修改。
首先,需要在model定义中添加版本管理器:
from django.contrib.admin.models import LogEntry from django.contrib.contenttypes.models import ContentType from django.db import models class MyModel(models.Model): # fields and methods here class Meta: verbose_name_plural = "MyModels" class MyModelVersionManager(models.Manager): def get_queryset(self): content_type = ContentType.objects.get_for_model(MyModel) return super(MyModelVersionManager, self).get_queryset().filter(content_type=content_type) class MyModelVersion(LogEntry): objects = MyModelVersionManager() class Meta: proxy = True verbose_name = "MyModel Version" verbose_name_plural = "MyModel Versions"
这里使用了Django内置的LogEntry
模型作为版本记录的基础,可以通过继承LogEntry
来扩展版本记录的字段和方法。
在MyModelVersionManager
中,使用ContentType
来获取MyModel的内容类型,然后使用super()
来获取所有版本,并只筛选出MyModel的版本。
最后,定义了一个MyModelVersion
模型,将其设置为代理模型,可以方便地对版本进行查询和比较,并添加了verbose_name
和verbose_name_plural
以便在管理界面中显示友好的名称。
接下来,在admin.py
中添加版本管理的视图:
from django.contrib import admin from django.contrib.admin.models import LogEntry from .models import MyModel, MyModelVersion class MyModelVersionInline(admin.TabularInline): model = MyModelVersion verbose_name = "Version" verbose_name_plural = "Versions" can_delete = False fields = ("action_time", "user", "action_flag", "change_message") class MyModelAdmin(admin.ModelAdmin): list_display = (...) inlines = [MyModelVersionInline] admin.site.register(MyModel, MyModelAdmin) admin.site.register(LogEntry)
这里使用了MyModelVersionInline
作为MyModelAdmin
的内联管理器,将版本记录添加到MyModelAdmin
的编辑界面中。
最后,可以在管理界面中查看和比较不同版本的修改。
对于回滚操作,可以使用Django的ORM和版本管理器来恢复到任意历史版本:
def rollback_to_version(model_instance, version_id): try: version = model_instance.versions.get(pk=version_id) for field, value in version.changed_data.items(): setattr(model_instance, field, value) model_instance.save() except MyModelVersion.DoesNotExist: pass
这个函数接受两个参数:model_instance
是要回滚的模型实例,version_id
是要恢复的版本ID。使用get()
方法从版本管理器中获取版本记录,然后使用版本记录的changed_data
属性恢复模型实例的属性,并保存模型实例。如果指定的版本记录不存在,则跳过恢复操作。
相关文章