You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django DRF如何实现无需URL传pk的当前用户详情查询与编辑ViewSet

你遇到的报错是因为将lookup_field设为空字符串导致的,DRF生成路由时会使用该字段拼接路径正则,空值会导致正则分组名缺失,触发配置错误,该参数不需要修改,按以下步骤配置即可实现需求:

1. 调整ViewSet配置

首先添加登录权限校验,重写get_object方法直接返回当前登录用户,不需要依赖URL传入的pk参数:

from rest_framework.permissions import IsAuthenticated

class UserDetailsViewSet(
    mixins.UpdateModelMixin,
    mixins.RetrieveModelMixin,
    viewsets.GenericViewSet,
):
    serializer_class = UserDetailsSerializer
    # 限制仅登录用户可访问该接口
    permission_classes = [IsAuthenticated]

    def get_object(self):
        # 直接返回当前登录用户,无需从queryset过滤
        return self.request.user

这里不需要保留原有的queryset属性,也不需要修改lookup_field参数。

2. 调整路由配置

默认的router.register会自动生成带pk的详情路径,我们可以选择两种方式适配需求:

方式一:手动写路由映射(推荐,路径完全匹配需求)

放弃使用router注册该视图,手动绑定请求方法到对应视图动作:

from django.urls import path
from .views import UserDetailsViewSet

urlpatterns = [
    # 路径为你需要的 /userdetail/,支持GET查、PUT全量更新、PATCH部分更新
    path('userdetail/', UserDetailsViewSet.as_view({
        'get': 'retrieve',
        'put': 'update',
        'patch': 'partial_update'
    })),
    # 其他业务路由...
]

方式二:用@action装饰器保留router注册

如果你希望继续使用router统一注册所有视图,可以用装饰器自定义无pk的接口:

from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

class UserDetailsViewSet(viewsets.GenericViewSet):
    serializer_class = UserDetailsSerializer
    permission_classes = [IsAuthenticated]

    # detail=False表示是列表级别接口,路径不带pk;url_path=''保证路径就是根路径
    @action(detail=False, methods=['get', 'put', 'patch'], url_path='')
    def current_user(self, request):
        if request.method == 'GET':
            serializer = self.get_serializer(request.user)
            return Response(serializer.data)
        # 处理更新请求
        partial = request.method == 'PATCH'
        serializer = self.get_serializer(request.user, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

这种方式依旧可以用router.register(r"userdetail", UserDetailsViewSet)注册路由,最终接口路径就是你需要的/userdetail/。

内容的提问来源于stack exchange,提问作者Santhosh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 06:24:03