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_class
和 serializer_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):
希望这可以帮助您更好地理解其余框架视图的内部结构!
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_class
和 serializer_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):
希望这可以帮助您更好地理解其余框架视图的内部结构!