DRF, remove primary key from routed extra action

Viewed 410

I have a view with some extra actions:


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)

And I'm using the default router in my url:

months_router = DefaultRouter()
months_router.register('months', MonthsViewSet, 'months')
urlpatterns = [
    path('', include(months_router.urls)),
]

So currently this is my URL:

/months/{date}/get_last_year/

the date is the primary key in my model.

Is there any way to change the action decorator settings to NOT use the primary key?

so the URL would become:

/months/get_last_year/
1 Answers

From the 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.

set detail=False in your decorator.

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