[英]How to build a Django REST-Api that returns a custom list of models?
我在使用Django Rest Framework构建我的API时遇到了很多麻烦。 我好几天都被困在同一个问题上了。 我已经尝试了很多解决方案和代码片段并且问了很多人,但无济于事。 我试图遵循文档中的所有说明,但对我来说,它们不清楚且不完整。 因此,我非常渴望一个清晰,简洁,完整的工作示例来解决我的问题。
现在这是我的问题:
我按照这里的说明成功构建了一个简单的Django Rest API。 这些指令使构建API非常容易,该API返回特定模型的所有实例的列表,或基于用户提供的ID的单个实例。 所以,因为我有一个名为MyObject的模型,所以我构建了一个api,当你点击URL / api / myObjects时会返回所有myObjects的列表。 如果我点击URL / api / myObjects / 60,它会给我带ID为= 60的myObject。 到现在为止还挺好!
但我不想这样做。 我想要一些更复杂的东西。 myObject模型有一个名为getCustomObjects()的方法。 此方法本身返回myObjects列表。 当我点击URL / api / myObjects / 60时,我希望它返回通过在ID == 60的myObject上调用getCustomObjects()生成的列表。 这个看似简单的变化让我非常头疼,我无法弄清楚如何去做。 原因是因为我想返回一个非标准的对象列表,我不能使用标准的方法来处理模型中描述的ModelViewSet。 当我做出我认为应该有效的更改时,我会收到错误。 我当前的错误是: 未指定base_name
参数,并且无法自动确定视图集中的名称,因为它没有.model
或.queryset
属性。 。 我读过的所有文件都可以解决这个错误,我说我需要指定一个“base_name”参数。 该base_name参数的值应该是什么以及我应该如何在我的URL中使用它对我来说非常不清楚。 我没有一个很好的解释。 这就是我发布完整代码的原因。 如果有人可以清楚地告诉我如何解决它,我将非常感激。
我的路线在myApp的url.py中看起来像这样:
from rest_framework import routers
router = routers.DefaultRouter() router.register(r'myObjects/(?P<id>\d+)/?$', views.MyObjectsViewSet)
url(r'^api/', include(router.urls)),
我的模型看起来像这样:
class MyObject(models.Model):
name = models.TextField()
我的Serializer看起来像这样:
class MyObjectSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = MyObject
fields = ('id', 'name',)
我的Viewset看起来像这样:
class MyObjectsViewSet(viewsets.ViewSet):
def retrieve(self,request,pk=None):
queryset = MyObjects.objects.get(pk=pk).customMyObjectList()
if not queryset:
return Response(status=status.HTTP_400_BAD_REQUEST)
else:
serializer = MyObjectSerializer(queryset)
return Response(serializer.data,status=status.HTTP_200_OK)
当我点击/ api / myObjects / 60 /时出现以下错误:
`base_name` argument not specified, and could not automatically determine the name from the viewset, as it does not have a `.model` or `.queryset` attribute.
base_name
以便路由器可以正确地命名URL。 您正在使用的DefaultRouter使用视图集的模型或查询集属性。 但由于您使用的viewsets.ViewSet都没有,因此路由器无法确定用于命名生成的URL模式的基本名称(例如,'myobject-detail'或'myobject-list')
router.register(r'myObjects', views.MyObjectsViewSet, base_name='myobject')
这将导致创建以下URL模式: ^myObjects/{pk}/$
,其名称为: 'myobject-detail'
。
请注意, router.register
的第一个参数必须是r'myObjects'
而不是r'myObjects/(?P<id>\\d+)/?$'
因为路由器只需要前缀并负责创建模式。 总结一下,这是DRF文档的摘录
register()方法有两个必需参数:
prefix - 用于此路由集的URL前缀。
viewset - 视图集类。
(可选)您还可以指定其他参数:
base_name - 用于创建的URL名称的基础。 如果未设置,将根据视图集上的模型或queryset属性自动生成基本名称(如果有)。 请注意,如果视图集不包含模型或查询集属性,则必须在注册视图集时设置base_name。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.