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

查看:158
本文介绍了如何构建一个返回自定义模型列表的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,方法是按照 这里 。这些指令使得构建一个返回一个特定模型的所有实例的列表或基于用户提供的ID的单个实例的API非常容易。所以,因为我有一个名为MyObject的模型,所以我创建了一个api,当你点击URL / api / myObjects时,它返回所有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.

我的路线在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)),

我的模型看起来像这样:

My Model looks like this:

class MyObject(models.Model):
    name = models.TextField()

我的串行器看起来像这样:

My Serializer looks like this:

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

我的视图看起来像这样:

My Viewset looks like this:

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使用视图集的model或queryset属性。但是,由于您使用的viewets.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} / $ ,名称为:code> '为MyObject细节'。

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

注意 router.register 的第一个参数必须是 r'myObjects' code> not r'myObjects /(?P< id> \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:


前缀 - 用于此路由集合的URL前缀。

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

viewset - 视图集。 / p>

viewset - The viewset class.

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

Optionally, you may also specify an additional argument:

base_name - 用于创建的URL名称的基础。如果取消设置
,则基于模型
或视图集上的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-guide/routers

See routers docs: www.django-rest-framework.org/api-guide/routers

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

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