查询Django ModelAdmin钩子执行顺序及内联模型日志注入方案
Django ModelAdmin钩子执行顺序与内联模型日志注入方案
一、官方文档相关说明
Django官方文档没有直接提供ModelAdmin钩子的完整调用路径清单,但在ModelAdmin核心流程的文档中,会零散提及各钩子的触发时机:
- 保存流程的核心钩子执行顺序大致为:
save_model()→save_form()→save_related()(内联模型的保存逻辑在save_related()中处理) - 删除流程的执行顺序为:
delete_model()→delete_queryset()(批量删除场景触发) - 内联模型的表单处理,会在父ModelAdmin的
save_related()阶段触发,内联自身的save_formset()方法会被调用
二、内联模型增删改的日志注入方案
要为内联模型的操作单独添加LogEntry,无需依赖父ModelAdmin的日志生成逻辑,可通过以下方式实现:
1. 自定义内联类并覆盖钩子
创建InlineModelAdmin的子类,覆盖对应方法来注入日志:
from django.contrib.admin.models import LogEntry, CHANGE, ADDITION, DELETION from django.contrib.contenttypes.models import ContentType class YourInline(admin.TabularInline): model = YourInlineModel def save_formset(self, request, form, formset, change): # 获取待保存的内联实例 instances = formset.save(commit=False) for obj in instances: # 根据实例是否已有主键判断是新增还是修改 action_flag = CHANGE if obj.pk else ADDITION LogEntry.objects.log_action( user_id=request.user.pk, content_type_id=ContentType.objects.get_for_model(obj).pk, object_id=obj.pk, object_repr=str(obj), action_flag=action_flag, change_message=f"{'修改' if change else '新增'}内联对象" ) formset.save_m2m() super().save_formset(request, form, formset, change) def delete_queryset(self, request, queryset): # 为删除的内联对象添加日志 content_type = ContentType.objects.get_for_model(queryset.model) for obj in queryset: LogEntry.objects.log_action( user_id=request.user.pk, content_type_id=content_type.pk, object_id=obj.pk, object_repr=str(obj), action_flag=DELETION, change_message="删除内联对象" ) super().delete_queryset(request, queryset)
2. 关联至父ModelAdmin
将自定义内联类添加到父ModelAdmin的inlines列表即可生效:
class ParentModelAdmin(admin.ModelAdmin): inlines = [YourInline]
三、补充说明
- 父ModelAdmin的
save_related()会在自身save_model()执行后触发,此时内联表单集已处理完成,若需在父模型保存后再处理内联日志,也可覆盖父ModelAdmin的save_related()方法 - LogEntry的
change_message可根据需求自定义,比如添加具体修改的字段内容等细节
内容的提问来源于stack exchange,提问作者John Dowling
相关产品推荐
相关产品推荐

