python - 如何构建返回自定义模型列表的 Django REST-Api?

标签 python django api rest

我在尝试使用 Django Rest Framework 构建我的 API 时遇到了很多麻烦。几天来我一直被困在同一个问题上。我尝试了许多解决方案和代码片段,并询问了很多人但无济于事。我已尝试按照文档中的所有说明进行操作,但对我来说它们不清楚且不完整。所以我非常迫切需要一个清晰、简洁、完整的工作示例来解决我的问题。

现在这是我的问题:

我已经按照说明成功构建了一个简单的 Django Rest API here .这些说明使构建 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 参数,并且无法从 View 集中自动确定名称,因为它没有 .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()

我的序列化器看起来像这样:

class MyObjectSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = MyObject
    fields = ('id', 'name',)

我的 View 集是这样的:

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 使用 View 集的模型或查询集属性。但是由于您使用的 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 文档的摘录

There are two mandatory arguments to the register() method:

prefix - The URL prefix to use for this set of routes.

viewset - The viewset class.

可选地,您还可以指定一个附加参数:

base_name - 用于创建的 URL 名称的基础。如果未设置 basename 将根据模型自动生成 或 View 集上的查询集属性(如果有的话)。请注意,如果 View 集不包含模型或查询集属性,则必须在注册 View 集时设置 base_name。

查看路由器文档:www.django-rest-framework.org/api-guide/routers

关于python - 如何构建返回自定义模型列表的 Django REST-Api?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22108636/

相关文章:

python - 在提取数据集后,一些单词显示不正确的方式

Python:检查嵌套列表是否在嵌套列表中

php - paypal api dodirectpayment nvp php 没有响应

php - 使用 CS-Cart 通过 API 添加商品到购物车

python - 我可以将 2 字节大小的变量作为 1 字节大小的变量发送吗?

python - 如何更改 Anaconda Navigator 中 PowerShell 的默认目录?

Django-mptt TreeManyToManyField 不工作?

python - 更改 request.GET QueryDict 值

python - Django反向查找外键不起作用

Python 使用用户名、密码和 API key 连接到 API