我在“/me”端点上有一个视图集,不需要使用lookup_field来进行详细说明,因为它使用当前请求用户进行过滤,检索单个结果。
class ClientProfileDetail(
mixins.RetrieveModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet
):
permission_classes = [IsOwnerOrAdmin]
queryset = ClientProfile.objects.all()
serializer_class = ClientProfileSerializer
def get_object(self):
queryset = self.get_queryset()
obj = get_object_or_404(queryset, pk=self.request.user)
return obj
我正在使用默认路由器注册视图集:
router.register(r"me", ClientProfileDetail)
但即使我对 URL 没有用处,路由器也会注册这些 URL:
profile/ ^me/(?P<pk>[^/.]+)/$ [name='clientprofile-detail']
profile/ ^me/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='clientprofile-detail']
我的问题是:如何删除路线上的
(?P<pk>[/.]+)/$
重写 get_object() ,如下所述:不带查找字段的RetrieveAPIView?不起作用
您可以重写 DefaultRouter 中的
get_routes
方法。就我而言,我添加了条件 viewset.lookup_field is None
,以便每个具有 None Lookup_field 的视图集在 URL 中都没有 Lookup_field。
class Router(DefaultRouter):
single_routes = [
# Dynamically generated list routes. Generated using
# @action(detail=False) decorator on methods of the viewset.
DynamicRoute(
url=r'^{prefix}/{url_path}{trailing_slash}$',
name='{basename}-{url_name}',
detail=False,
initkwargs={}
),
# Detail route.
Route(
url=r'^{prefix}{trailing_slash}$',
mapping={
'get': 'retrieve',
'put': 'update',
'post': 'create',
'patch': 'partial_update',
'delete': 'destroy'
},
name='{basename}-detail',
detail=False,
initkwargs={'suffix': 'Instance'}
),
# Dynamically generated detail routes. Generated using
# @action(detail=True) decorator on methods of the viewset.
DynamicRoute(
url=r'^{prefix}/{url_path}{trailing_slash}$',
name='{basename}-{url_name}',
detail=False,
initkwargs={}
),
]
def get_routes(self, viewset: GenericViewSet):
if viewset.lookup_field is None:
default_routes = self.single_routes
else:
default_routes = self.routes
known_actions = list(flatten([route.mapping.values() for route in default_routes if isinstance(route, Route)]))
extra_actions = viewset.get_extra_actions()
# checking action names against the known actions list
not_allowed = [
action.__name__ for action in extra_actions
if action.__name__ in known_actions
]
if not_allowed:
msg = ('Cannot use the @action decorator on the following '
'methods, as they are existing routes: %s')
raise ImproperlyConfigured(msg % ', '.join(not_allowed))
# partition detail and list actions
detail_actions = [action for action in extra_actions if action.detail]
list_actions = [action for action in extra_actions if not action.detail]
routes = []
for route in default_routes:
if isinstance(route, DynamicRoute) and route.detail:
routes += [self._get_dynamic_route(route, action) for action in detail_actions]
elif isinstance(route, DynamicRoute) and not route.detail:
routes += [self._get_dynamic_route(route, action) for action in list_actions]
else:
routes.append(route)
return routes
你可以尝试一下
class ClientProfileDetail(mixins.UpdateModelMixin, viewsets.GenericViewSet):
permission_classes = [IsOwnerOrAdmin]
queryset = ClientProfile.objects.all()
serializer_class = ClientProfileSerializer
def get(request, *args, **kwargs):
serilizer = self.serializer_class(request.user, many=False)
return Response(serilizer.data)