1

バージョンのreversion.modelsから履歴としてjsonデータを返す関数があります。

from django.http import HttpResponse
from reversion.models import Version
from django.contrib.admin.models import LogEntry
import json
def history_list(request):
    history_list = Version.objects.all().order_by('-revision__date_created')
    data = []
    for i in history_list:
        data.append({
            'date_time': str(i.revision.date_created),
            'user': str(i.revision.user),
            'object': i.object_repr,
            'field': i.revision.comment.split(' ')[-1],
            'new_value_field': str(i.field_dict),
            'type': i.content_type.name,
            'comment': i.revision.comment
        })

    data_ser = json.dumps(data)
    return HttpResponse(data_ser, content_type="application/json")

上記のスニペットを実行すると、出力jsonが次のようになります

[{"type": "fruits", "field": "colour", "object": "anyobject", "user": "anyuser", "new_value_field": "{'price': $23, 'weight': 2kgs, 'colour': 'red'}", "comment": "Changed colour."}]

上記の関数から、

'comment': i.revision.comment

json を "comment": "changed color" として返します。color は、コメントから取得するために関数に記述したフィールドです。

'field': i.revision.comment.split(' ')[-1]

しかし、field_dict からフィールド名と値を取得する方が良い方法だと思います

問題: 上記の json リストから、new_field_value と old_value をフィルター処理したいと思います。new_filed_value では色の値のみ。

4

1 に答える 1

1

変更されたフィールドを取得するのは、コメントをチェックするほど簡単ではありません。これはオーバーライドできるからです。

Django-reversion比較するのではなく、各バージョンを保存するだけです。

django-reversion-compareモジュールとそのadmin.pyコードを確認することをお勧めします。

そこにあるコードの大部分は、きれいに並べられた HTML 差分ページを生成するように設計されていますが、オブジェクトごとに変更されたフィールドのリストを生成するためにコードを再利用できるはずです (複数のフィールドが存在する可能性があるため)。バージョンごとに変更されたフィールド)。


*コードに、ある時点で変更されたフィールドを取得するためのビューに依存しない方法が含まれている必要がありますが、これで開始できるはずです。

from reversion_compare.admin import CompareObjects
from reversion.revisions import default_revision_manager

def changed_fields(obj, version1, version2):
    """
    Create a generic html diff from the obj between version1 and version2:
        A diff of every changes field values.
    This method should be overwritten, to create a nice diff view
    coordinated with the model.
    """
    diff = []

    # Create a list of all normal fields and append many-to-many fields
    fields = [field for field in obj._meta.fields]
    concrete_model = obj._meta.concrete_model
    fields += concrete_model._meta.many_to_many

    # This gathers the related reverse ForeignKey fields, so we can do ManyToOne compares
    reverse_fields = []
    # From: http://stackoverflow.com/questions/19512187/django-list-all-reverse-relations-of-a-model
    changed_fields = []
    for field_name in obj._meta.get_all_field_names():
        f = getattr(
            obj._meta.get_field_by_name(field_name)[0],
            'field',
            None
        )
        if isinstance(f, models.ForeignKey) and f not in fields:
            reverse_fields.append(f.rel)

    fields += reverse_fields

    for field in fields:
        try:
            field_name = field.name
        except:
            # is a reverse FK field
            field_name = field.field_name

        is_reversed = field in reverse_fields
        obj_compare = CompareObjects(field, field_name, obj, version1, version2, default_revision_manager, is_reversed)

        if obj_compare.changed():
            changed_fields.append(field)

    return changed_fields

これは、次のように呼び出すことができます。

changed_fields(MyModel,history_list_item1, history_list_item2)

様々な現品history_list_item1history_list_item2対応しておりVersionます。

*: 寄稿者として、私はそれを正しく取得します。

于 2015-03-09T03:18:10.937 に答える