djangodjango-rest-framework

How do I log filtered GET requests on a Django REST Framework ModelViewSet using @action?


I have a ModelViewSet for EventReportLink and need to log every time someone queries with ?event_report__id=<id>. I’ve tried adding a custom @action(detail=False, methods=['get']), but I’m not sure if I’m implementing it correctly or if there’s a better way.

I added:

@action(detail=False, methods=['get'], url_path='log-test')
def log_test(self, request):
    event_report_id = request.query_params.get('event_report__id')
    logger.info(f"ID: {event_report_id}")
    queryset = self.filter_queryset(self.get_queryset())
    serializer = self.get_serializer(queryset, many=True)
    return Response(serializer.data)

Expecting logs and correct filtering results. I’m receiving filtered results but not sure if this is best practice. What would be a more idiomatic approach?

P.S. I also consulted this related question, which discusses how to add behavior before/after the default create logic using super().create(request). However, I wasn’t entirely sure if it applies to my case with query param filtering and logging via @action, so I’m still exploring best practices.


Solution

  • It seems like the simplest approach would be to look at the function you want to add logging for, then write a function with the same name and call the superclass to trigger the existing behavior.

    For example, you want to hook the list method of your ModelViewSet, which is defined inside the ListModelMixin.

    You could write that method within your view set like this:

        def list(self, request, *args, **kwargs):
            event_report_id = request.query_params.get('event_report__id')
            logger.info(f"ID: {event_report_id}")
            return super().list(request, *args, **kwargs)