Объект типа <Model> не сериализуемый JSON

Если у меня есть GFK, такие как модели наследования Assets (Asset.model, имеющий asset_id, asset_name и Account, OneType.model, SecondType.model, все наследуются от модели Asset и т.д. на основе это), и я хочу предоставить Конечная точка API для всех активов в моем Account, я мог бы иметь (не уверен, что это соглашение) свойство модели Account, которое представляет собой список, расширяющий различные типы активов:

#Account model
@property
def assets(self):
    assets = []
    assets.extend(self.onetype_set.all())
    assets.extend(self.secondtype_set.all())
    …
    return assets

Мне понадобится сериализатор для учетной записи

class AccountSerializer(serializers.ModelSerializer):

    # filter to assets for the user
    def get_queryset(self):
        return Account.objects.filter(organization=self.request.user)

    class Meta:
        model = Account
        fields = ('assets', )

и я предполагаю, что для каждого типа активов

class OneTypeSerializer(serializers.ModelSerializer):
    class Meta:
        model = OneType
        fields = ('asset_id', 'asset_name',)
class SecondTypeSerializer(serializers.ModelSerializer):
    …
…

но я продолжаю получать сообщение об ошибке: Object of type 'OneType' is not JSON serializable (я понимаю, что ошибка означает, что мне нужно, чтобы модель была сериализована в JSON, но я думал, что модель вызовет сериализатор модели ...)

Трассировка стека кажется бесполезной из-за внутренней работы наборов представлений DRF, но вот она:

/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py in default
            else:
                return list(iterable)
            # Let the base class default method raise the TypeError
            return JSONEncoder.default(self, o)
    """
    raise TypeError("Object of type '%s' is not JSON serializable" %
                    o.__class__.__name__) ...
def encode(self, o):
    """Return a JSON string representation of a Python data structure.
    >>> from json.encoder import JSONEncoder
    >>> JSONEncoder().encode({"foo": ["bar", "baz"]})

▼ Local vars
Variable    Value
o           <OneType: AssetName - Type 1 : Account 2>
self        <rest_framework.utils.encoders.JSONEncoder object at 0x11dce1668>

Viewsets.py:

class AssetViewSet(viewsets.ModelViewSet):
    """
    This viewset automatically provides `list`, `create`, `retrieve`, `update` and `destroy` actions.
    """
    serializer_class = AssetSerializer
    permission_classes = (permissions.IsAuthenticated, IsOrganizationMember,)

    def get_queryset(self):
        slug = self.kwargs['slug']
        return Account.objects.filter(slug=slug)

Кроме того, это скорее проблема DRF (я не использую правильный набор запросов) или проблема с питоном (я не предоставляю сериализуемый метод / класс для объекта / класса)?

Это явно проблема DRF, хотя в то время я не помню, какой для этого был бы правильный код. Я предполагаю, что вам нужно назначить assets = ... в вашем классе AccountSerializer, но вместо ..., вероятно, должен быть какой-то волшебный полиморфный сериализатор, который применял бы правильный сериализатор для каждого элемента списка.

Mikhail Burshteyn 19.09.2018 22:36

Обратите внимание, что объявление OneTypeSerializer с model = OneType в его мета-мете не включает автоматическую сериализацию OneType с этим сериализатором во всех местах.

Mikhail Burshteyn 19.09.2018 22:42

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

Mikhail Burshteyn 19.09.2018 22:42

@chris Frisina похоже, что вы пытаетесь вернуть экземпляр OneType из класса / функции просмотра. Итак, проверьте представление или добавьте соответствующее представление

JPG 20.09.2018 06:08

Вам нужно будет предоставить свой код представления, чтобы получать более полезные ответы.

Linovia 20.09.2018 07:43

@JPG, Все они основаны на базовых классах.

chris Frisina 25.09.2018 18:26

Приведенные здесь фрагменты кода не показывают, как предполагается сериализовать ресурсы. Мы мало чем можем здесь помочь.

Linovia 26.09.2018 10:08

@Linovia, на самом деле я заставил его работать, выполнив следующие действия в сериализаторе учетных записей assets = serializers.StringRelatedField (many = True), на который намекал из заметок Михаила, но я думаю, что могут быть другие способы, возможно, с разными архитектурами, учитывая разные подходы к ГФК вроде проблем. Оставайся позитивным!

chris Frisina 26.09.2018 17:20
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
8
1 343
0

Другие вопросы по теме