用JSON Api实现DRF的最佳方法,其中不涉及任何模型?

问题描述 投票:1回答:1

我已经有一段时间了。任何指导表示赞赏。

我必须使用带有分页的JSON API输出来实现django rest_framework。似乎很简单。我已经做过很多次了。但是这次我没有基础模型可以使用。

我的数据来自第三方SDK,该SDK仅返回词典列表。它是带有嵌套列表等的复杂数据,但最后只是字典列表。

我已经到了可以显示我的数据甚至对其进行分页的地步。但是我的输出中没有“链接”,也没有任何“下一个”,“上一个”或“计数”字段。

我在这里发布我的代码段,更改名称以不公开第三者提供者。

这里是我到目前为止的序列化器:

from rest_framework import serializers

class MySerializer(serializers.Serializer):
    def to_representation(self, instance):
        return instance

这是我的观点:

class MyViewSet(ViewSet):
    serializer_class = serializers.MySerializer
    queryset = sdk.get_all_the_things()

    def list(self, request):
        page = self.paginate_queryset(self.queryset)
        return Response(page)

sdk.get_all_the_things()返回字典列表,类似于:

[{ 
  "foo": "something",
  "bar": "more stuff", 
  ...
 },
 {
  ...
 },


and so on....
]

我无法直接控制此输入,并且底层的dict结构可能随时更改。同样,字典的格式并不是那么关键。

这似乎可行(但是),但是如前所述,分页链接丢失了。我认为这是因为self.paginate_queryset(self.queryset)。我似乎找不到任何其他原因,也无法从谷歌搜索中获得任何帮助。

我尝试过使用序列化器的方法

    serializer = serializers.MySerializer(self.queryset, many=True)
    return Response(serializer.data)

这只是给我可怕的'dict'对象没有属性'pk'。我猜是因为它正在期待模型对象。

我的智慧到此为止,再次提供任何指导将不胜感激。

python django django-rest-framework json-api
1个回答
0
投票

好失去了很多睡眠,但我终于想通了。事实证明,问题不在于DRF本身,而是django-rest-framework-json-api软件包中的一个限制。一旦我禁用了json_api渲染器,一切就会开始工作。但是JSON:API是必需的,所以我不得不继续努力。...

我设法通过创建一个虚拟对象并用这些对象填充列表来使其正常工作。我在这里发布我的解决方案,以防其他任何人遇到此问题并需要一个解决方案:

首先,我创建一个虚拟对象:

class DummyObject(object):
    def __init__(self, **kwargs):
        for field in ('id', 'data'):
            setattr(self, field, kwargs.get(field, None))

然后必须操纵字典列表。这有点丑陋,但是行得通:

resultset = sdk.get_all_the_things()
index = 0
instances = []

for instance in resultset:
    temp_obj = DummyObject()
    temp_obj.data = instance
    temp_obj.pk = index
    instances.append(temp_obj)
    index += 0
return instances

然后更改了我的序列化程序以序列化对象数据:

from . import DummyObject

class MySerializer(serializers.Serializer):
    pk = serializers.IntegerField(read_only=True)
    data = serializers.DictField()

    def create(self, validated_data):
        return DummyObject(pk=None, **validated_data)

    class Meta:
        resource_name = 'instances'

这将列表中的每个字典转换为一个对象,然后我可以向其添加'pk'属性。

© www.soinside.com 2019 - 2024. All rights reserved.