在不涉及模型的情况下使用 JSON Api 实施 DRF 的最佳方法?

Bast way to implement DRF with JSON Api where no model is involved?

我从事此工作已有一段时间了。任何指导表示赞赏。

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

我的数据来自第三方 SDK,它只是 returns 字典列表。它是带有嵌套列表等的复杂数据,但最终它只是一个字典列表。

我已经到了能够显示我的数据甚至对其进行分页(某种程度)的地步。但是在我的输出中没有 "links" 也没有任何 "next"、"prev" 或 "count" 字段。

我在这里发布我的代码片段,更改名称以不公开第 3 方提供商。

这是我目前拥有的序列化程序:

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() returns 字典列表,类似于:

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


and so on....
]

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

这似乎(有点)有效,但如前所述,分页链接丢失。我认为这是因为 self.paginate_queryset(self.queryset)。我似乎找不到任何其他原因,谷歌搜索也没有任何帮助。

我试过使用序列化程序

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

这只是给我可怕的 'dict' 对象没有属性 'pk'。我猜是因为它需要一个模型对象。

我已经无计可施了,所以再次感谢您的指导。

好的。失眠了很多,但我终于想通了。原来问题不在于 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' 属性添加到该对象。