我的路由中需要什么base_name参数才能使这个Django API工作?

时间:2014-02-27 23:38:25

标签: python django rest

我正在构建一个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的路径应该是什么样的吗?

7 个答案:

答案 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)

this是一个有用的答案,请阅读详细信息。

<强> TL;博士

它被用作生成的URL模式的基本名称(例如,'myobject-detail'或'myobject-list')。

答案 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的。