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
相关产品推荐
相关产品推荐

