Rest_framework 列表中的数据

Rest_framework datas from list

django rest_framework 如果您想要公开的数据来自数据库,则效果很好,但是如果数据仅来自一个列表(字典),情况会怎样? rest_framework 是否支持表示这样的数据?:

[
    {'id': 1, 'name': 'apple'},
    {'id': 2, 'name', 'banana'},
    {'id': 3, 'name': 'orange'},
]

.

如果确定数据永远不会改变(因此无需将它们放入数据库,因为我们只讨论不到 10 个元素),实现我的目标的最佳方法是什么?

我想在 django 1.6+ 中将列表转换为伪造的 QuerySet 已经不可能了......

Rest_framework版本:3.1.1 Django 版本:1.7.x

.

对于任意对象,您只需遵循文档:

from rest_framework import serializers

class Fruit(object):
    def __init__(self, id, name):
        self.id = id
        self.name = name

class FruitSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField(max_length=200)

然后:

fruits = [Fruit(id=1, name="apple"),
          Fruit(id=2, name="banana"),
          Fruit(id=3, name="orange"),]

serializer = FruitSerializer(fruits, many=True)
serializer.data
# [
#     {'id': 1, 'name': 'apple'},
#     {'id': 2, 'name': 'banana'},
#     {'id': 3, 'name': 'orange'}
# ]

序列化器适用于任何类型的对象,不一定是 django 模型:如果您查看此 docs 页面的第二段,您会发现它们定义了任意对象并将其序列化。

您的分页 pastebin 大部分是正确的,您唯一缺少的是通用视图的一些内部工作。

简答

# define custom model for your list object
class ListElement(object):
    def __init__(self, id, name):
        self.id = id
        self.name = name

# define your serializer normally
class ListSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField(max_length=50)

class MyListView(generics.ListAPIView):
    pagination_class = LargeSet
    serializer_class = ListSerializer

    def get_queryset(self):
        dt = [{'name': 'apple', 'id': 1}, 
              {'name': 'banana', 'id': 2},
              {'name': 'pear', 'id': 3}, 
              {'name': 'plum', 'id': 4}]
        return dt

长答案

序列化器仅适用于任何通用对象,它们与 Django 查询集或模型无关,因此您可以序列化任何自定义对象,如上所示。

我将首先添加一些上下文:通用视图继承了一些 mixins,这些 mixin 为每个添加了一些辅助功能。 例如,在您的情况下,您的 ListAPIView 定义如下:class ListAPIView(mixins.ListModelMixin, GenericAPIView).

让我们看一下 List mixin docs:

Provides a .list(request, *args, **kwargs) method, that implements listing a queryset. If the queryset is populated, this returns a 200 OK response, with a serialized representation of the queryset as the body of the response. The response data may optionally be paginated.

你可以相信我的话,list 方法也可以为你处理分页,但是我们可以查看源代码,因为它们提供了一个很好的想法 work inside:

def list(self, request, *args, **kwargs):
    queryset = self.filter_queryset(self.get_queryset())

    page = self.paginate_queryset(queryset)
    if page is not None:
        serializer = self.get_serializer(page, many=True)
        return self.get_paginated_response(serializer.data)

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

代码很清楚,只需要注意它使用了get_queryset方法。

现在,您可能想知道为什么在简短的回答中我没有在视图的 get 请求处理程序中使用 list 方法。原因很简单,ListAPIView 已经为您做到了!

# get method of the ListAPIView
def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

所以唯一要做的就是指定:

  • 分页class
  • 查询集
  • 序列化器class

正如 genericAPIView 期望看到的那样。 分页 class 和序列化程序 class 始终相同,因此您可以将它们放在适当的 class 属性 (pagination_classserializer_class);如果不是这种情况,您将覆盖 get_serializer_class 并为 pagination_class 定义 属性 getter(但这是另一回事)。

那么查询集呢?

由于您是动态生成查询集,因此不能使用queryset class 属性 来设置它,而是我们重写 get_queryset 方法(上面调用的在源代码中,如果你还记得的话)并做任何我们需要的事情来获取我们的查询集并 return 它。

因此是简短答案中的代码。

还有更多

viewsets 可以为您做更多的工作,因为它们继承自所有标准混合宏,并让您可以使用更高级别的方法处理您的请求,例如 list , 创建, 销毁, 等等

您还可以在 docs

中找到 genericAPIView 提供的大部分有用方法

你当然可以使用 mixin 来提供 ModelViewSet 功能的一个子集,以防你想出一些奇怪的操作组合

# this one will provide the create and list methods only
# In fact it is the viewset equivalent of the ListCreateAPIView
class ListCreateViewSet(mixins.CreateModelMixin,
                        mixins.ListModelMixin,
                        GenericViewSet):

希望这可以帮助您更好地理解其余框架视图的内部结构!