6

我正在使用 django-simple-history (1.8.1) 和 DRF (3.5.3)。我想获得一个包含每个元素历史的休息服务。举个例子吧!

模型.py

class Product(models.Model):
    name = models.CharField(max_length=50)
    price = models.IntegerField()
    history = HistoricalRecords()

    def __str__(self):
        return self.name

那么,什么必须是serializers.py?我想得到类似的东西:

[
    {
        "id": 1,
        "name": "Apple",
        "price": 8,
        "history": [
            {
                "history_id": 1,
                "id": 1,
                "name": "Apple",
                "price": 0,
                "history_date": "2016-11-22T08:02:08.739134Z",
                "history_type": "+",
                "history_user": 1
            },
            {
                "history_id": 2,
                "id": 1,
                "name": "Apple",
                "price": 10,
                "history_date": "2016-11-22T08:03:50.845634Z",
                "history_type": "~",
                "history_user": 1
            },
            {
                "history_id": 3,
                "id": 1,
                "name": "Apple",
                "price": 8,
                "history_date": "2016-11-22T08:03:58.243843Z",
                "history_type": "~",
                "history_user": 1
            }
        ]
    }
]

在没有找到解决方案的情况下搜索后,我终于自己找到了。但如果有人有更好的解决方案......

4

3 回答 3

10

我知道已经一年了,但无论如何,也许有人觉得它有用。这是我的解决方案(对我来说似乎更容易):

一个新的序列化器字段:

class HistoricalRecordField(serializers.ListField):
    child = serializers.DictField()

    def to_representation(self, data):
        return super().to_representation(data.values())

现在只需将其用作序列化程序中的 aa 字段:

history = HistoricalRecordField(read_only=True)

这利用了 DRF 的内置listdict序列化程序,唯一的技巧是传递正确的可迭代对象,这是通过调用.values()简单历史模型管理器类来完成的。

于 2017-12-08T15:11:21.420 回答
7

这是我的解决方案。在serializers.py中:

from rest_framework import serializers
from .models import Product


class sHistory(serializers.ModelSerializer):
    def __init__(self, model, *args, fields='__all__', **kwargs):
        self.Meta.model = model
        self.Meta.fields = fields
        super().__init__()

    class Meta:
        pass


class sProduct(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'

    history = serializers.SerializerMethodField()

    def get_history(self, obj):
        model = obj.history.__dict__['model']
        fields = ['history_id', ]
        serializer = sHistory(model, obj.history.all().order_by('history_date'), fields=fields, many=True)
        serializer.is_valid()
        return serializer.data

有用 !我对此感到非常自豪!有什么建议么 ?

于 2016-11-22T08:18:36.193 回答
3

似乎有一种更清晰更简单的方法

class AnySerializer(serializers.ModelSerializer):    
    history = serializers.SerializerMethodField()

    class Meta:
        model = MyModel
        fields = (....
                  ....
                  'history',
                  )
        read_only_fields = ('history',)

    def get_history(self, obj):
        # using slicing to exclude current field values
        h = obj.history.all().values('field_name')[1:]
        return h
于 2020-03-31T20:29:29.557 回答