Django Rest 框架 - “详细信息”:“未找到。”

Posted

技术标签:

【中文标题】Django Rest 框架 - “详细信息”:“未找到。”【英文标题】:Django Rest Framework - "detail": "Not found." 【发布时间】:2016-01-27 05:13:54 【问题描述】:

您好,在执行此请求时:groups/25010a31-fc5b-47c8-9c5c-d740e5743f52/members/4/ - 我得到“详细信息”:“未找到”

但是,如果您查看查询集,我已经打印了 Groupmember 实例,而这最终会打印出该特定实例,如此清晰地存在它?

查看:

class MemberDetail(mixins.RetrieveModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.UpdateModelMixin,
                   generics.GenericAPIView):
    serializer_class = GroupMembersSerializer
    lookup_field = "user_id"
    lookup_url_kwarg = "uuid"

    def get_queryset(self):
        group = self.kwargs["uuid"]
        user_id = self.kwargs["user_id"]
        print GroupMember.objects.get(group = group, user_id = user_id)
        return GroupMember.objects.get(group = group, user_id = user_id)

    def get(self, request, *args, **kwargs):
        return self.retrieve(self, request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(self, request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(self, request, *args, **kwargs)

网址:

 urlpatterns = [

    url(r'^$', views.GroupList.as_view()),
    url(r'^(?P<uuid>[^/]+)/$', views.GroupDetail.as_view()),
    url(r'^(?P<uuid>[^/]+)/members/$', views.MemberList.as_view()),
    url(r'^(?P<uuid>[^/]+)/members/(?P<user_id>[0-9]+)/$', views.MemberDetail.as_view()),

] 

有什么帮助吗?

【问题讨论】:

我马上看到一件事:您的get_queryset 返回单个对象而不是查询集。我认为您的意思是 filter 而不是 get @Ivan Filter 结果同样的问题 请发布您的网址。 @RahulGupta 网址已添加 @Danny 这真的很奇怪——你的网址都不包含"group"(通常类似于r'^group/(?P&lt;uuid&gt;[^/]+))。通常路由器会寻找"group-detail",但找不到。我错过了什么吗? 【参考方案1】:

在我的 routers.py 文件中,我是这样写的

router.register(r'',PersonViewSet)
router.register(r'PersonEmployee',PersonEmployeeViewSet)

所以我改成

router.register(r'PersonEmployee',PersonEmployeeViewSet)
router.register(r'',PersonViewSet)

它是先读取空路径 URL 并抛出未找到详细信息,所以我最后将路由器保留为空路径,它工作正常。

【讨论】:

【参考方案2】:

通常在安装 Django rest framework 数据表时会出现此错误,请检查设置中 Rest Framework 配置的下一个值:

REST_FRAMEWORK = 
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
        'rest_framework_datatables.renderers.DatatablesRenderer',
    ),
    'DEFAULT_FILTER_BACKENDS': (
        'rest_framework_datatables.filters.DatatablesFilterBackend',
    ),
    'DEFAULT_PAGINATION_CLASS': 'rest_framework_datatables.pagination.DatatablesPageNumberPagination',
    'PAGE_SIZE': 50,
    'EXCEPTION_HANDLER': 'utils.rest_framework.views.exception_handler'

【讨论】:

【参考方案3】:

只是想补充。在我查看 queryset 的情况下,没有返回带有预期对象的查询集,所以就您的问题的变化而言:

class MemberDetail(generics.GenericAPIView):
    serializer_class = GroupMembersSerializer
    queryset = GroupMember.objects.filter(...)

改为:

queryset = GroupMember.objects.all()

【讨论】:

【参考方案4】:

首先,您需要在get_queryset() 方法中返回一个查询集。

另外,您错误地将lookup_url_kwarg 定义为uuid。它实际上应该是user_id,因为这个url kwarg 值用于在get_queryset() 方法返回的查询集中执行uuid lookup_field 的查找。

如果未设置,lookup_url_kwarg 的默认值与lookup_field 的值相同。所以,我们甚至不需要定义lookup_url_kwarg。它将从lookup_field 计算。

class MemberDetail(mixins.RetrieveModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.UpdateModelMixin,
                   generics.GenericAPIView):
    serializer_class = GroupMembersSerializer
    lookup_field = "user_id" # no need to define 'lookup_url_kwarg' as both have same value

    def get_queryset(self):
        group = self.kwargs["uuid"]
        return GroupMember.objects.filter(group = group) # return a queryset

get_queryset() 方法中,我们只使用group 进行过滤,而不是使用user_id,因为只要有retrieve 请求,DRF 就会自行执行。

在查询集上使用.get() 将返回一个对象而不是查询集。要根据lookup_field 的值执行过滤,我们需要一个查询集。现在,.filter() 返回一个查询集,所以我们在这里使用它。

注意:当您返回 GroupMember.objects.filter(group = group, user_id = user_id) 时,retrieve 尝试在 user_id 字段上执行此返回查询集的查找,其值为 lookup_url_kwarg 值,即 user_id=25010a31-fc5b-47c8-9c5c-d740e5743f52。由于该查询集中不存在这样的对象,因此它返回了该错误。

【讨论】:

@RagulGupta 谢谢,这行得通 - 你能解释一下为什么它是 .filter 而不是 .get @Danny 更新了答案。 @RagulGupta 我很感激! 在我的情况下,模型字段与 url kwarg 的名称不同。在这种情况下,您可以将它们设置为不同的值,例如 lookup_field="model_field_name"lookup_url_kwarg="url_kwarg_name"

以上是关于Django Rest 框架 - “详细信息”:“未找到。”的主要内容,如果未能解决你的问题,请参考以下文章

在 Django Rest 框架 URL 中通过唯一 ID 但不是 PK 获取详细信息

django rest框架返回视图中的选定字段

Django REST 仅列表(无详细信息)

如何使用 Django oAuth 工具包从 Django Rest Framework 获取请求的应用程序详细信息

如何使用 Django Rest Framework 为列表和详细信息视图设置不同的序列化程序?

如何使用 Django Rest Framework 为列表和详细信息视图设置不同的序列化程序?