Django Rest Framework - "detail": "Not found."

23

嗨,在执行这个请求时:groups/25010a31-fc5b-47c8-9c5c-d740e5743f52/members/4/ - 我收到 "detail": "Not found" 的回复。

但是,如果您查看我打印的 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()),

] 

需要帮忙吗?


3
我看到的一件事是:你的get_queryset返回单个对象而不是查询集。我认为你应该使用filter而不是get - Ivan
@Ivan 用相同的问题“过滤”结果 - Danny
1
请发布您的URL。 - Rahul Gupta
@Danny 这不是一个完整的答案,我只是指出了一个错误。 - Ivan
1
@Danny 这真的很奇怪——你的url中没有一个包含"group"(通常是类似于r'^group/(?P<uuid>[^/]+)这样的内容)。通常路由器会寻找"group-detail",但没有找到。我有什么遗漏吗? - Ivan
显示剩余2条评论
4个回答

17

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

此外,你错误地将lookup_url_kwarg定义为uuid。实际上它应该是user_id,因为这个url的kwarg值用于从get_queryset()方法返回的查询集中执行uuidlookup_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
@Danny 已更新答案。 - Rahul Gupta
@RagulGupta 我感激不尽! - Danny
在我的情况下,模型字段的名称与URL关键字参数的名称不同。在这种情况下,您可以将它们设置为不同的值,例如 lookup_field="model_field_name"lookup_url_kwarg="url_kwarg_name" - MarMat

9
在我的情况下,我在我的 routers.py 文件中这样写:
router.register(r'',PersonViewSet)
router.register(r'PersonEmployee',PersonEmployeeViewSet)

所以我把它改成了

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

首先,它会先读取空路径 URL,并抛出“详细信息未找到”的错误。因此,我将带有空路径的路由器放在最后,这样就可以正常工作。


3

通常出现这个错误是因为你安装了Django rest framework datatables,请检查设置中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'
}

1

我想补充一下。在我看的那个例子中,queryset 没有返回预期的对象,所以关于你的问题,改动会是这样的:

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

改为中文:

改为:

queryset = GroupMember.objects.all()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接