我目前正在开发一个用于记录对模型字段所做更改的应用程序。更改记录为{"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 %}

10-07 19:32
查看更多