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

Posted

技术标签:

【中文标题】Django REST 框架 RetrieveAPIView 获取空的“id”参数并返回 404 错误【英文标题】:Django REST framework RetrieveAPIView gets empty "id" parameter and returns 404 error 【发布时间】:2019-02-04 05:38:50 【问题描述】:

我使用 Django 1.11 + Django REST 框架。我正在尝试使用来自 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]

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

这段代码有什么问题?

【问题讨论】:

你可以将它们合并成一个ViewSet 【参考方案1】:

问题是你的正则表达式匹配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 页。 1 /api/pages/1

【讨论】:

我错过了 regex 部分。为此 +1 :) 非常感谢您,dirkgroten! ِ其实我放错了')'。【参考方案2】:

原来的问题是结束括号(正则表达式),你放错地方了。

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

除此之外,您应该将 urls 模式更改为 sensible 形式,如

#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/

上提供

【讨论】:

感谢您的快速回答。我不认为问题出在这个 urls 文件中。问题是 urls.py 中的第一行(对于 TestPageList.as_view())工作得很好并返回记录列表。只有第二个有问题。 'id' == '' 结果。在 Django 版本中可能有问题(我使用 1.11,而不是 2.x)?

以上是关于Django REST 框架 RetrieveAPIView 获取空的“id”参数并返回 404 错误的主要内容,如果未能解决你的问题,请参考以下文章

带有 Django 2.0 的 Django REST 框架 URL

Django REST框架 -1

django.test.client 上的 Django rest 框架导入错误

Django Rest 框架令牌认证

使用 django-allauth 和 django-rest 框架

Django rest框架认证测试