2016-11-22 6 views
2

Я использую django-simple-history (1.8.1) и DRF (3.5.3). Я хочу получить сервис отдыха, содержащий историю каждого элемента. Давайте возьмем пример!Получение истории отдыха от Django simple История

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 
      } 
     ] 
    } 
] 

После поиска whitout найти решение, я, наконец, нашел его сам. Но если у кого-то есть лучшее решение ...

ответ

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 

Это работает! Я очень горжусь этим! какие-либо предложения ?

0

Я знаю, что это был год, но в любом случае, может быть, кто-то сочтет это полезным. Вот мое решение (кажется, гораздо проще для меня):

Новое поле сериализатору:

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() в классе менеджера моделей с простой историей.