我目前正在开发一个用于记录对模型字段所做更改的应用程序。更改记录为{"field": field.name, "old_value": old_value, "new_value": new_value}
中的JSON字符串textfield
。
如何获取JSON字符串的特定键/值?当前代码:
views.py
def userChangelog(request, pk):
user = User.objects.get(pk = pk)
changelogs = ChangeLog.objects.filter(user_id = pk)
context = {
'user': user,
'changelogs': changelogs,
}
return render(request, 'users/backend/user/user_changelog.html', context)
模板
{% for changelog in changelogs %}
<p>1. {{ changelog.user }}</p>
<p>2. {{ changelog.changes }}</p>
<p>3. {{ changelog.date_of_change }}</p>
{% endfor %}
理想情况下,我想执行
<p>2. {{ changelog.changes.field }} changed from {{ changelog.changes.old_value }} to {{ changelog.changes.new_value }}</p>
,但似乎无法弄清楚如何仅将查询的一部分转换为json.loads
,并将其显示在模板中。编辑-ChangeLog模型
class ChangeLog(models.Model):
user = models.ForeignKey(User, related_name = 'changed_by', on_delete = models.CASCADE)
content_type = models.ForeignKey(ContentType, models.SET_NULL, verbose_name = _('content type'), blank = True, null = True,)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
changes = models.TextField(_('changes'), blank = True)
date_of_change = models.DateTimeField(_('change time'), default = timezone.now, editable = False,)
objects = ChangeLogManager()
class Meta:
verbose_name = _('Change log entry')
verbose_name_plural = _('Change log entries')
def change_message(request, obj, old_instance):
new_instance = obj.objects.get(pk = old_instance.pk)
ct = ContentType.objects.get_for_model(new_instance)
for field in obj._meta.get_fields():
if isinstance(field, models.ManyToOneRel):
continue
old_value = getattr(old_instance, field.name)
new_value = getattr(new_instance, field.name)
if old_value != new_value:
change_message = json.dumps({"field": field.name, "old_value": old_value, "new_value": new_value})
ChangeLog.objects.log_update(
user = request,
content_type = ct,
content_object = new_instance,
object_id = new_instance.pk,
changes = change_message,
date_of_change = timezone.now()
)
最佳答案
如果您不想使用第三方软件包。您可以在ChangeLog
模型中添加一个属性,该属性可以解析并返回JSON更改。 cached_property很有用,因为它使您停止解析每次访问的更改
@cached_property
def changes_dict(self):
return json.loads(self.changes)
比您可以在模板中使用它
{% for changelog in changelogs %}
<p>1. {{ changelog.user }}</p>
<p>2. {{ changelog.changes_dict.field }}</p>
<p>2. {{ changelog.changes_dict.old_value }}</p>
<p>2. {{ changelog.changes_dict.new_value }}</p>
<p>3. {{ changelog.date_of_change }}</p>
{% endfor %}