我在尝试使用 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。
关于python - 如何构建返回自定义模型列表的 Django REST-Api?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22108636/