删除从视图集上的路由器生成的未使用的lookup_field

问题描述 投票:0回答:2

我在“/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?不起作用

python django django-rest-framework django-views
2个回答
0
投票

您可以重写 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

-3
投票

你可以尝试一下

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)
© www.soinside.com 2019 - 2024. All rights reserved.