如何从django-simple-history获取_history_user_id并生成HTML表格?
解决django-simple-history历史修改用户字段的访问问题
问题背景
使用django-simple-history的simple_history.middleware.HistoryRequestMiddleware追踪模型修改用户,UI显示正常,但生成修改记录HTML报告时,获取到的是模型本身的user字段ID,而非历史表中记录修改操作的history_user_id。尝试添加_history_user属性未解决,需获取历史表的history_user_id关联的用户信息并整合到报告中。
原模型代码
class Degree(TimeStampedModel): user = ForeignKey(User, null=True, blank=True, related_name='degrees', on_delete=CASCADE) level = CharField(max_length=50, null=True, blank=True, choices=LEVELS) institution = CharField(max_length=255, null=True) major = CharField(max_length=255, null=True, blank=True) minor = CharField(max_length=255, null=True, blank=True) verified_date = DateField(null=True, blank=True) graduation_date = DateField(null=True, blank=True) reason_for_change = CharField(max_length=255, null=True) history = HistoricalRecords(User)
原报告视图代码
def Changelog_table(request): name = 'Changelog' desc = 'changelog' headers = [ ('', ''), ('user__last_name', 'Last name'), ('user__first_name', 'First name'), ('reason_for_change', 'Reason for change'), ('section', 'section'), ('modified', 'modified'), ('user', 'user') ] filters = { 'user__is_active': True, } values = [ 'user__username', 'user__last_name', 'user__first_name', 'reason_for_change', 'section', 'modified', 'user', ] qs_degree = ( Degree.objects.filter(**filters) \ .values_list(*values) ) return render(request, 'reports/report.html', { 'headers': headers, 'data': json.dumps(list(qs_degree), cls=DjangoJSONEncoder), 'name': name, 'desc': desc, })
尝试过的无效修改(添加_history_user属性)
class Degree(TimeStampedModel): user = ForeignKey(User, null=True, blank=True, related_name='degrees', on_delete=CASCADE) level = CharField(max_length=50, null=True, blank=True, choices=LEVELS) institution = CharField(max_length=255, null=True) major = CharField(max_length=255, null=True, blank=True) minor = CharField(max_length=255, null=True, blank=True) verified_date = DateField(null=True, blank=True) graduation_date = DateField(null=True, blank=True) reason_for_change = CharField(max_length=255, null=True) history = HistoricalRecords(User) @property def _history_user(self): return self.user
解决方案
核心问题是原代码查询的是Degree主表,而所有修改记录(包括修改者信息)存储在django-simple-history自动生成的HistoricalDegree历史表中。需调整查询逻辑到历史表,并正确关联history_user字段。
步骤1:修正模型定义
移除HistoricalRecords的User参数,删除无用的_history_user属性。HistoryRequestMiddleware会自动从请求中获取当前用户并绑定到历史记录的history_user字段:
class Degree(TimeStampedModel): user = ForeignKey(User, null=True, blank=True, related_name='degrees', on_delete=CASCADE) level = CharField(max_length=50, null=True, blank=True, choices=LEVELS) institution = CharField(max_length=255, null=True) major = CharField(max_length=255, null=True, blank=True) minor = CharField(max_length=255, null=True, blank=True) verified_date = DateField(null=True, blank=True) graduation_date = DateField(null=True, blank=True) reason_for_change = CharField(max_length=255, null=True) history = HistoricalRecords() # 无需传入User参数
步骤2:修改报告视图,查询历史表
将查询对象切换到HistoricalDegree,并添加历史用户的关联字段:
def Changelog_table(request): name = 'Changelog' desc = 'changelog' # 调整表头,区分原数据用户和修改操作用户 headers = [ ('', ''), ('user__last_name', '原用户姓氏'), ('user__first_name', '原用户名字'), ('history_user__last_name', '修改者姓氏'), ('history_user__first_name', '修改者名字'), ('reason_for_change', '修改原因'), ('history_date', '修改时间'), ('history_type', '操作类型'), ] # 可选:过滤历史记录类型,只保留新增/修改记录 filters = { 'history_type__in': ['+', '~'], # +=新增,~=修改,-=删除 } # 指定需要查询的字段,包含历史用户的信息 values = [ 'user__username', 'user__last_name', 'user__first_name', 'history_user__username', 'history_user__last_name', 'history_user__first_name', 'reason_for_change', 'history_date', 'history_type', ] # 查询历史表,按修改时间倒序排列 qs_degree_history = ( HistoricalDegree.objects.filter(**filters) .order_by('-history_date') .values_list(*values) ) return render(request, 'reports/report.html', { 'headers': headers, 'data': json.dumps(list(qs_degree_history), cls=DjangoJSONEncoder), 'name': name, 'desc': desc, })
关键说明
HistoricalDegree是django-simple-history自动生成的历史模型,命名规则为Historical+原模型名- 通过
history_user__xxx可以访问历史表中history_user_id关联的用户信息 history_date记录修改操作的时间,history_type记录操作类型(新增/修改/删除)
内容的提问来源于stack exchange,提问作者Invisible
相关产品推荐
相关产品推荐

