DRF,从路由的额外操作中删除主键

DRF, remove primary key from routed extra action

我有一些额外操作的视图:


class MonthsViewSet(ModelViewSet):
    authentication_classes = (TokenAuthentication,)

    def get_queryset(self):
        query_set = Month.objects.filter(user=self.request.user)
        return query_set

    serializer_class = MonthSerializer

    @swagger_auto_schema(
        manual_parameters=[AUTH_HEADER_PARAM, MonthParameters.DATE, MonthParameters.DAYS, MonthParameters.FARM])
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    @action(detail=True)
    def get_next_year(self, *args, **kwargs):
        """
        Return the next 12 months.
        """
        first_month, last_month = get_12_months(last=False)
        query_set = self.get_queryset().filter(date__range=(first_month, last_month))
        serializer = MonthSerializer(query_set, many=True)
        return Response(serializer.data, status.HTTP_200_OK)

    @action(detail=True)
    def get_last_year(self, *args, **kwargs):
        """
        Return the last 12 months available.
        """
        first_month, last_month = get_12_months(last=True)
        print(first_month, last_month)
        query_set = self.get_queryset().filter(date__range=(first_month, last_month))
        serializer = MonthSerializer(query_set, many=True)
        return Response(serializer.data, status.HTTP_200_OK)

我在 url:

中使用默认路由器
months_router = DefaultRouter()
months_router.register('months', MonthsViewSet, 'months')
urlpatterns = [
    path('', include(months_router.urls)),
]

所以目前这是我的 URL:

/months/{date}/get_last_year/

日期是我模型中的主键。

有什么方法可以将动作装饰器设置更改为不使用主键吗?

所以 URL 会变成:

/months/get_last_year/

来自DRF doc,

Like regular actions, extra actions may be intended for either a single object, or an entire collection. To indicate this, set the detail argument to True or False. The router will configure its URL patterns accordingly.

在装饰器中设置detail=False

@action(<b>detail=False</b>)
def get_last_year(self, *args, **kwargs):
    # res of your code