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

Saq*_*Ali 8 python api django rest

我在使用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)),
Run Code Online (Sandbox Code Playgroud)

我的模型看起来像这样:

class MyObject(models.Model):
    name = models.TextField()
Run Code Online (Sandbox Code Playgroud)

我的Serializer看起来像这样:

class MyObjectSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = MyObject
    fields = ('id', 'name',)
Run Code Online (Sandbox Code Playgroud)

我的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)
Run Code Online (Sandbox Code Playgroud)

当我点击/ 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.
Run Code Online (Sandbox Code Playgroud)

alm*_*lki 17

base_name使用,以便路由器可以正确地命名URL.您正在使用的DefaultRouter使用视图集的模型或查询集属性.但由于您使用的viewsets.ViewSet都没有,因此路由器无法确定用于命名生成的URL模式的基本名称(例如,'myobject-detail'或'myobject-list')

router.register(r'myObjects', views.MyObjectsViewSet, base_name='myobject')
Run Code Online (Sandbox Code Playgroud)

这将导致创建以下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.

请参阅路由器文档:www.django-rest-framework.org/api-guide/routers