Django REST框架RetrieveAPIView获取空的“ id”参数并返回404错误

时间:2018-08-29 12:19:00

标签: django django-rest-framework

我使用Django 1.11 + Django REST Framework。我正在尝试使用Django REST Framework中的通用RetrieveAPIView获取有关不同记录的详细数据,并且服务器返回“ HTTP 404 Not Found”结果,即无数据。

models.py 文件:

class TestPage( models.Model):
    title = models.CharField(  size = 120)
    counter = models.IntegerField( default = 0)
    def __unicode__(self):
        return u'' + self.title

serializers.py 文件:

class TestPageSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ('id', 'title', 'counter',)
        model = models.TestPage

urls.py 文件:

urlpatterns = [
    url( r'^admin/', admin.site.urls),
    url( r'^api/', include( 'rest_framework.urls')), 
    url( r'^api/', include( 'testpages.urls')),  
    ]

testpages / urls.py 文件:

urlpatterns = [
    url( r'^$', views.TestPageList.as_view()),
    url( r'^(?P<id>)\d+/$', views.TestPageDetail.as_view()),  
    ]

以及最后的 views.py 文件:

class TestPageList(generics.ListAPIView):
    lookup_field = 'id'
    queryset = TestPage.objects.all()
    serializer_class = TestPageSerializer

class TestPageDetail(generics.RetrieveAPIView):
    lookup_field = 'id'
    queryset = TestPage.objects.all()
    serializer_class = TestPageSerializer
    # def get_object( self):
    #    print self.kwargs

如果我为列表中的所有记录请求“ http://127.0.0.1:8000/api/”,则服务器将返回所有记录。但是,例如,如果我想使用“ http://127.0.0.1:8000/api/1/”通过ID进行记录,则会得到空的结果,如下图所示。

[![在此处输入图片描述] [1]] [1]

如果我在最后两行中取消注释get_object()函数,则可以在终端中看到{'id':u''},即服务器获取空参数'id'。

此代码有什么问题?

2 个答案:

答案 0 :(得分:3)

问题是您的id的正则表达式匹配,实际上是您要匹配的\d+放在匹配组之外:

url(r'^(?P<id>\d+)/$', views.TestPageDetail.as_view())

顺便说一句,要成为一名优秀的REST公民,您不应该在特定对象的URL末尾添加/

注意:正如JPG所提到的,为要获取的资源(多个)添加名称是正确的RESTful:

url(r'^pages/(?P<id>\d+)$', views.TestPageDetail.as_view())

这样,您获取nr页。 /api/pages/1

1

答案 1 :(得分:2)

最初的问题是 结束语种 (正则表达式),您将其放错了位置。

urlpatterns = [
    url(r'^$', views.TestPageList.as_view()),
    url(r'^(?P<id>\d+)/$', views.TestPageDetail.as_view()),
                    ^^^ here
]

除此之外,您应该将网址格式更改为 明智 形式,例如

#testpages/urls.py
urlpatterns = [
    url(r'^test/$', views.TestPageList.as_view()),
    url(r'^test/(?P<id>\d+)/$', views.TestPageDetail.as_view()),
]

list-api 将会在 /api/test/ 端点
detail-api 将在 /api/test/{id}/

上可用