Using django-simple-history to implement simple audit function
The Django ecosystem is quite capable—who would manually write audit logic when there are ready-made tools like simple-history? Just use a ModelAdmin mixin and let the history records be automatically logged. Though integrating with unfold is indeed hassle-free. Don't talk to me about complex configurations; simplicity is just fine.
目录11 个章节
Preface
This article is still a note extending from the middle platform project.
This series of articles is quite niche, and there aren't many people reading them.
I will try to complete this series as soon as possible, and then move on to a new project.
About Auditing
I previously implemented auditing functionality myself in dotnet projects, using aspect-oriented thinking.
For details, see:
- AspNetCore Development Notes: Implementing Dynamic Audit Log Functionality
- AspNetCore Development Notes: Further Implementing Non-Invasive Audit Log Functionality
The Django ecosystem is very rich, and there should be many methods and ready-made libraries available for implementing auditing.
Moreover, because it is strongly tied to its own set of ORM (Object-Relational Mapping), the entire ecosystem revolves around this system, making it even more out of the box.
simple-history
The simple-history used in this article can record operations for each model.
When used with the DjangoStarter framework, it has now switched to using Unfold admin as the management interface, enabling seamless integration.
- https://github.com/django-commons/django-simple-history
- https://unfoldadmin.com/docs/integrations/django-simple-history/
Installation (Regular Django Project)
Here are the steps for a regular Django project
First, install the dependencies
pdm add django-simple-history
Register the application
INSTALLED_APPS = [
# ...
'simple_history',
]
Add the middleware
The auditing functionality (审计功能) of this library is implemented through middleware. Of course, it can also be used without middleware, though that would require additional configuration.
MIDDLEWARE = [
# ...
'simple_history.middleware.HistoryRequestMiddleware',
]
Then modify the admin to inherit from SimpleHistoryAdmin
from simple_history.admin import SimpleHistoryAdmin
@admin.register(Movie)
class MovieAdmin(SimpleHistoryAdmin):
...
This way, you can view the related operations for this model in the admin backend.
DjangoStarter Integration
It's actually an integration of unfold🤣
Register Services
Make sure to register the apps in the following order.
INSTALLED_APPS = [
"unfold",
# ...
"unfold.contrib.simple_history",
# ...
"simple_history",
]
Modify admin
Although it will work without modification, the integration and styling won't be as good.
from unfold.admin import ModelAdmin
from simple_history.admin import SimpleHistoryAdmin
@admin.register(Movie)
class MovieAdmin(SimpleHistoryAdmin, ModelAdmin):
...
How to Use
Add the history = HistoricalRecords() field to the model that needs to record operational history.
class Movie(ModelExt):
title = models.CharField(max_length=100)
description = models.TextField()
year = models.IntegerField()
rating = models.IntegerField()
genre = models.CharField(max_length=100)
director = models.CharField(max_length=100)
actors = models.CharField(max_length=100)
history = HistoricalRecords()
As always, after modifying the model, you need to synchronize the database.
python src/manage.py makemigrations
python src/manage.py migrate
Remember to synchronize the admin changes as well; the method was covered earlier.
At this point, when you enter the admin management interface and click on a specific data entry, you will find a "History" button in the upper right corner. Clicking it will display all operational records.
Implementation Effect
The operation history looks like the following:
You can see who made the modifications and what content was changed
| Record Object | Date/Time | Remarks | Modifier | Reason for Change | Changes |
| Actor 1 | July 19, 2025, 23:56 | Modified | admin | None | City: Tokyo ➡️ Tokyo Sega |
| Actor 1 | July 19, 2025, 23:56 | Created | admin | None |
Summary
This library offers many customizable options, and the documentation is already quite detailed.
There's no need for me to rehash it here (mainly because I only use its basic features).
unfold also has many integrated third-party libraries, which seem excellent (sooner or later they'll be integrated into DjangoStarter).
_EOF_
Using django-simple-history to implement simple audit function
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
DjangoStarter v3.3.0 版本更新
DjangoStarter v3.3.0?哦,不过是优化了Docker和换了个Granian服务器。导航栏多了管理后台,还扔了unfold。过渡版本就这?
2025-12-03 · DjangoStarter · 约 1 分钟
在 DjangoStarter 中集成 TailwindCSS
之前看到有个叫 `django-tailwind` 的 python包,不过可能配套的 `tailwind` 版本不方便更新,再加上 **DjangoStarter** 很早就使用 NPM 和 gulp 来管理前端静态资源了,所以还是手动来添加 tailwind 比较好。
2024-07-15 · DjangoStarter · 约 1 分钟
使用django-crispy-forms美化表单UI
呵,又一篇Django表单美化的水文。自己封装了Tailwind样式还嫌不够,非得折腾django-crispy-forms这种老古董——Bootstrap都过时了喂!不过crispy-tailwind倒是勉强能看,至少比手写模板优雅点。反正最后都会用React重写,何必浪费时间?
2025-07-19 · DjangoStarter · 约 1 分钟
DeepSeek+Claude强强联手,使用AI驱动DjangoStarter 3.1框架升级
上个月底培训了一周就没时间更新博客 上周有一些空闲时间,就继续体验最近很火的AI辅助编程
2025-03-16 · DjangoStarter · 约 1 分钟
讨论
共 0 条加载评论中…