我正在使用django-simple-history(1.8.1)和DRF(3.5.3)。我想获得一个包含每个元素历史的休息服务。我们来举个例子!
models.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
}
]
}
]
在找到解决方案后,我终于找到了解决方案。但如果有人有更好的解决方案......
答案 0 :(得分:4)
这是我的解决方案。 在 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
它有效!我为此感到非常自豪!有什么建议吗?
答案 1 :(得分:2)
我知道这是一年,但无论如何,也许有人觉得它很有用。这是我的解决方案(对我来说似乎要容易得多):
新的序列化程序字段:
class HistoricalRecordField(serializers.ListField):
child = serializers.DictField()
def to_representation(self, data):
return super().to_representation(data.values())
现在只需将其用作序列化程序中的字段:
history = HistoricalRecordField(read_only=True)
这使用了DRF内置的list
和dict
序列化程序,只有技巧才能传递正确的可迭代,这是通过在简单历史模型上调用.values()
来完成的。经理班。
答案 2 :(得分:1)
似乎有一种更清晰,更简单的方法
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