我正在构建一个Django应用程序,它公开了一个REST API,用户可以通过它查询我的应用程序的模型。我按照说明here。
我的路线在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()
我的Serializer看起来像这样:
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 /时出现以下错误:
未指定
base_name
参数,并且无法自动确定视图集中的名称,因为它没有.model
或.queryset
属性。
我从here了解到我的路线上需要一个base_name参数。但是从文档来看,我不清楚base_name参数的值应该是什么。有人可以告诉我使用base_name的路径应该是什么样的吗?
答案 0 :(得分:41)
尝试在urls.py中执行此操作。第三个参数'Person'可以是你想要的任何东西。
router.register(r'person/food', views.PersonViewSet, 'Person')
答案 1 :(得分:13)
在您的情况下,或许您只需要为路由器设置base_name
参数,并使用对象名称MyObject
。
router.register(r'myObjects/(?P<id>\d+)/?$', views.MyObjectsViewSet, base_name="MyObject")
http://www.django-rest-framework.org/api-guide/routers/#Usage
答案 2 :(得分:6)
让我解释一下,为什么我们首先需要 base_name ,然后让我们进入 base_name 的可能值。
如果之前曾经使用过Django网址而没有其余框架(DRF),那么您可以像这样指定它:
urlpatterns = [
url(r'myObjects/(?P<id>\d+)/?$', views.MyObjectsListView.as_view(), name='myobject-list'),
url(r'myObjects/(?P<id>\d+)/?$', views.MyObjectsDetailView.as_view(), name='myobject-detail'),
]
在这里,如果您看到,有一个名称参数,用于标识当前命名空间(即应用)中的网址。
这正是django-rest-framework自动尝试做的事情,因为 drf 知道视图是列表还是详细信息(因为viewset)。它只需要附加一些前缀来区分网址。这就是 base_name (前缀)的目的。
在大多数情况下,您可以将网址或资源名称设为 base_name 。在您的情况下, base_name = myobject 。 DRF会生成 base_name + view_type 作为名称参数,例如 myobject_list &amp;的 myobject_detail 强>
注意:通常, base_name 将自动从 queryset 字段(从视图)中获取,因为它对于视图集中的所有视图类型都是相同的。但是,如果指定 get_queryset 方法而不是 queryset ,则可能意味着您对不同的视图类型(如列表,详细信息)具有不同的查询集。因此,DRF会要求您为资源的所有视图类型指定公共 base_name 。
答案 3 :(得分:3)
另一种解决方案可能是使用ModelViewSet,它将从模型中自动派生出基本名称。
请确保并告诉它使用哪种型号:
因为ModelViewSet扩展了GenericAPIView,所以通常需要 至少提供queryset和serializer_class属性,或者 模型属性快捷方式。
答案 4 :(得分:2)
简单地提一下,
queryset = MyObjects.objects.all()
像这样,
class MyObjectsViewSet(viewsets.ViewSet):
queryset = MyObjects.objects.all()
在views.py中相应的Viewset中,而不是在
下提及def retrieve()...
它为我工作:)
答案 5 :(得分:1)
答案 6 :(得分:0)
假设您的views.py中有两个函数可查询一堆员工。 一个查询仅名称(employeenameviewset),另一个查询地址(employeeinfoviewset)。 然后在您的urls.py中添加如下内容:
router.register(r'employee_names', views.employeenameviewset, basename="employees")
router.register(r'employee_details', views.employeeinfoviewset, basename="employees")
使用相同的基本名称,其余的URL将由Django自动创建,就像在URL Conf的情况下一样。实际上,这是基于URLConf的。