Django REST Framework: список различных сериализованных объектов?

У меня есть три разных типа объектов: RawArticle, RawPatent и RawGrant.

У меня есть отличные рабочие сериализаторы, базовым классом которых является serializers.ModelSerializer.

Если я получаю набор запросов RawArticle, я могу передать его непосредственно сериализатору с many=True, и вывод будет номинальным:

[{"save_link": "...", "published": "2014-01-18T20:39:54.086Z", }, {"save_link": "...", "published": "..."}, ...]

Этот ответ генерируется из следующего кода:

return Response(RawArticleSerializer(articles, many=True).data)

Теперь, когда у меня есть три разных объекта, я хотел бы соединить их в цепочку, как указано выше, но с соответствующими объектами.

Я пока безуспешно. Моя первоначальная идея заключалась в том, чтобы просто создать список сериализованных объектов и вернуть его (конечно, сериализованный) как таковой:

    all_latest = user_latest(request)['latest_articles']

    available_serializers = {RawArticle: RawArticleSerializer, RawGrant: RawGrantSerializer, RawPatent: RawPatentSerializer}
    serialized = []
    for article in all_latest:
        serialized.append((available_serializers[type(article)](article, many=False)).data)

    return Response(str(serialized))

Приведенный выше код не возвращает JSON, а дата и время не преобразуются в фактическую дату и время в виде строки.

Моя последняя попытка заключалась в использовании json.dumps и simplejson, и оба поднимали TypeError, говоря:

объект даты и времени не сериализуем.

Любой намек будет принят с благодарностью.


person ChrisR    schedule 20.01.2014    source источник


Ответы (2)


Лично для работы с сериализаторами я создаю в своих моделях метод serialize. Этот метод, в свою очередь, вызывает соответствующий код для сериализации данных.

В этом случае код будет выглядеть так:

class RawArticle(models.Model):
   def serialize(self):
       return RawArticleSerializer(self, many=False).data

Затем в вашем основном коде:

from rest_framework.renderers import JSONRenderer

all_latest = user_latest(request)['latest_articles']

serialized = [article.serialize() for article in all_latest]
return Response(JSONRenderer().render(serialized))

Даже если объекты не являются моделями, этот подход все равно должен работать.

person Sunny Nanda    schedule 20.01.2014
comment
На самом деле это возвращает строку. Возврат списка после того, как .data сделал свое дело, как я объясню в своем ответе ниже. - person ChrisR; 22.01.2014
comment
Недостаток хорошей практики: отделить логин сериализации от бизнес-сущностей. Я предложил подход только с: serialized = [RawArticleSerializer(article, many=False).data for article in all_latest] и удалить метод serialize() из класса RawArticle - person Rafa0809; 15.11.2017

Ответ Санни вернет JSON в виде строки (заключенной в двойные кавычки). Чтобы этого избежать, возврат списка делает то, что мне нужно:

    serialized = []
    AVAILABLE_SERIALIZERS = {RawArticle: RawArticleSerializer, RawGrant: RawGrantSerializer, RawPatent: RawPatentSerializer}
    for article in articles:
        serialized.append((AVAILABLE_SERIALIZERS[type(article)](article, many=False)).data)

    return Response(serialized)
person ChrisR    schedule 22.01.2014