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

如何在Django中实现带版本控制的持久化数据模型?

解决Django中带版本控制的数据库模型需求

Hey there! Great question—versioning database records so you can roll back changes is super common, and you’re right that there’s no need to reinvent the wheel here. Let’s break down the best solutions for your use case:

首选方案:用成熟的第三方包

These tools handle all the heavy lifting for you, no messy custom save/delete overrides required.

django-reversion

This is one of the most popular version control packages in the Django ecosystem, and it’s perfect for your needs:

  • Automatically tracks every create/update/delete action on your models
  • Lets you roll back to any historical version with a few lines of code
  • Integrates seamlessly with Django Admin (so you can view/restore versions right in the backend)
  • No need to manually rewrite core model methods

Quick setup steps:

  1. Install it:
pip install django-reversion
  1. Add it to your INSTALLED_APPS in settings.py:
INSTALLED_APPS = [
    # ... your other apps
    'reversion',
]
  1. Register your models (two easy options):
    • Option 1: Use VersionAdmin in your admin setup:
    from django.contrib import admin
    from reversion.admin import VersionAdmin
    from .models import YourModel
    
    @admin.register(YourModel)
    class YourModelAdmin(VersionAdmin):
        pass
    
    • Option 2: Use the decorator in your model file (works even if you don’t use Admin):
    import reversion
    from django.db import models
    from .abstracts import AbstractPersistentModel
    
    @reversion.register()
    class YourModel(AbstractPersistentModel):
        name = models.CharField(max_length=100)
        # ... your other fields
    
  2. Track changes in views (auto-saves versions when you modify objects):
from reversion.views import create_revision

def update_model(request, pk):
    obj = YourModel.objects.get(pk=pk)
    with create_revision():
        obj.name = "Updated Name"
        obj.save()
        # Optional: Add a comment to the version
        reversion.set_comment("Changed name to reflect new branding")

django-simple-history

Another fantastic choice—this one creates a dedicated history table for each of your models, logging every detail of changes (before/after values, who made the change, timestamps). It’s just as easy to use:

Quick setup:

  1. Install:
pip install django-simple-history
  1. Add to INSTALLED_APPS:
INSTALLED_APPS = [
    # ... your other apps
    'simple_history',
]
  1. Add the history tracker to your model:
from simple_history.models import HistoricalRecords
from django.db import models
from .abstracts import AbstractPersistentModel

class YourModel(AbstractPersistentModel):
    name = models.CharField(max_length=100)
    # Add this field to track history
    history = HistoricalRecords()
  1. Run migrations to create the history tables:
python manage.py makemigrations
python manage.py migrate

You can then access all historical versions and roll back easily:

# Get all past versions of an object
all_versions = obj.history.all()

# Roll back to the previous version
obj.history.first().instance.save()

If you want a custom (simplified) implementation

If you’d rather avoid third-party packages, you can tweak your abstract model to create version copies on save/delete. Here’s a cleaner approach:

from django.db import models
from django.utils.timezone import now

class AbstractPersistentModel(models.Model):
    time_created = models.DateTimeField(auto_now_add=True)
    time_changed = models.DateTimeField(null=True, default=None)
    time_deleted = models.DateTimeField(null=True, default=None)
    is_current = models.BooleanField(default=True)  # Marks the latest version

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        if self.pk is not None:
            # Clone the existing record as a non-current historical version
            old_instance = self.__class__.objects.get(pk=self.pk)
            old_instance.pk = None  # Generate new primary key
            old_instance.is_current = False
            old_instance.time_changed = now()
            old_instance.save()
        # Save the new current version
        self.is_current = True
        self.time_changed = now()
        super().save(*args, **kwargs)

    def delete(self, *args, **kwargs):
        # Soft delete: mark as deleted and save a historical version
        self.time_deleted = now()
        self.save()  # Triggers the save logic above to create a history entry

Note that this custom approach has limitations:

  • You’ll need to always filter for is_current=True when fetching active records
  • No built-in support for tracking which user made changes
  • Handling related models gets complicated fast (third-party packages solve this automatically)

Overall, I’d strongly recommend going with django-reversion or django-simple-history—they’re battle-tested, well-documented, and will save you hours of debugging.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:30:20