如何构建返回自定义模型列表的 Django REST-Api? [英] How to build a Django REST-Api that returns a custom list of models?

查看:31
本文介绍了如何构建返回自定义模型列表的 Django REST-Api?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm having a great deal of trouble trying build my API using the Django Rest Framework. I have been stuck on the same issue now for several days. I've tried numerous solutions and code-snippets and asked plenty of people but to no avail. I've tried to follow all the instructions in the docs, but to me they are unclear and incomplete. So I'm very desperate for a clear, concise, complete working example to solve me problem.

现在我的问题是:

我按照说明成功构建了一个简单的 Django Rest API 此处.这些说明使构建一个 API 变得非常容易,该 API 返回某个模型的所有实例的列表,或基于用户提供的 ID 的单个实例.因此,由于我有一个名为 MyObject 的模型,因此我构建了一个 API,当您点击 URL/api/myObjects 时,该 API 会返回所有 myObjects 的列表.如果我点击 URL/api/myObjects/60,它会给我 ID==60 的 myObject.到目前为止一切顺利!

I have been successful at building a simple Django Rest API by following the instructions here. These instructions make it very easy to build an API that returns a list of all instances of a certain model, or a single instance based on a user-provided ID. So, since I have a model named MyObject, I have built an api that returns a list of all the myObjects when you hit the URL /api/myObjects. If I hit the URL /api/myObjects/60, it gives me the myObject with ID==60. So far so good!

但我不想这样做.我想要更复杂的东西.myObject 模型有一个名为 getCustomObjects() 的方法.此方法本身返回一个 myObjects 列表.当我点击 URL/api/myObjects/60 时,我希望它返回通过在 ID==60 的 myObject 上调用 getCustomObjects() 生成的列表.这个看似简单的变化让我非常头疼,我不知道该怎么做.原因是因为我想返回一个非标准的对象列表,所以我不能像文档中描述的那样使用 ModelViewSet 的标准处理方式.当我进行我认为应该有效的更改时,我会收到错误消息.我当前的错误是:未指定 base_name 参数,并且无法从视图集中自动确定名称,因为它没有 .model.queryset 属性..我为解决此错误而阅读的所有文档都说我需要指定一个base_name"参数.这个 base_name 参数的值应该是什么以及我应该如何在我的 URL 中使用它对我来说非常不清楚.我没有很好的解释.这就是为什么我要发布我的完整代码.如果有人能清楚而完整地建议我如何解决它,我将不胜感激.

But I don't want to do this. I want something a bit more complex. The myObject model has a method called getCustomObjects(). This method itself returns a list of myObjects. When I hit the URL /api/myObjects/60, I want it to return the list produced by calling getCustomObjects() on the myObject with ID==60. This seemingly simple change is causing me a very major headache and I can't figure out how to do it. The reason is that because I want to return a non-standard list of objects, I cannot use the standard way of doing things with a ModelViewSet as described in the docs. When I make the changes that I think should work, I get errors. My current error is: 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.. All the docs I have read to cure this error say that I need to specify a "base_name" argument. What the value of that base_name argument should be and how I should use it in my URL are very unclear to me. I don't have a good explanation. That's why I'm posting my complete code. If someone can advise me clearly and completely how to fix it, I would be very grateful.

My Route 在 myApp 的 url.py 中如下所示:

My Route looks like this in myApp's 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()

我的序列化程序如下所示:

My Serializer looks like this:

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

我的视图集如下所示:

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/时,出现以下错误:

When I hit /api/myObjects/60/ I get the following error:

`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')

base_name is used so the router can properly name the URLs. The DefaultRouter you are using uses the model or queryset attributes of the view set. But since you are using viewsets.ViewSet which has neither, the router cannot determine the base name used to name the generated URL patterns (eg, 'myobject-detail' or 'myobject-list')

router.register(r'myObjects', views.MyObjectsViewSet, base_name='myobject')

这将导致创建以下 URL 模式:^myObjects/{pk}/$,名称为:'myobject-detail'.

This will result in creating the following URL pattern: ^myObjects/{pk}/$ with the name: 'myobject-detail'.

注意 router.register 的第一个参数必须是 r'myObjects' 而不是 r'myObjects/(?P\d+)/?$' 因为路由器只需要前缀并负责创建模式.总而言之,这是 DRF 文档的摘录

Notice the first param to router.register must be r'myObjects' not r'myObjects/(?P<id>\d+)/?$' because the router just needs the prefix and will take care of creating the patterns. To summarize this is an excerpt from DRF docs

register() 方法有两个强制参数:

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

prefix - 用于这组路由的 URL 前缀.

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

viewset - 视图集类.

viewset - The viewset class.

可选地,您还可以指定一个额外的参数:

Optionally, you may also specify an additional argument:

base_name - 用于创建的 URL 名称的基础.如果未设置basename 将根据模型自动生成或 viewset 上的 queryset 属性,如果有的话.请注意,如果视图集不包含模型或查询集属性,那么您必须在注册视图集时设置 base_name.

base_name - The base to use for the URL names that are created. If unset the basename will be automatically generated based on the model or queryset attribute on the viewset, if it has one. Note that if the viewset does not include a model or queryset attribute then you must set base_name when registering the viewset.

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

这篇关于如何构建返回自定义模型列表的 Django REST-Api?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆