Now I have the following logic implemented for a GET request in Django Rest Framework:
class SomeViewSet(mixins.ListModelMixin,
GenericViewSet):
count = None
def get_queryset(self):
query_set = ... # some_logic
self.count = query_set.count()
return query_set
def list(self, request, *args, **kwargs):
response = super().list(request, *args, **kwargs)
response.data = {'count': self.count,
'data': response.data}
return response
That is, the queryset is calculated according to complex logic, and it may contain a different number of objects that need to be returned in a GET request, since I don’t have access to the query_set variable inside the list function and I don’t want to copy the query_set calculation logic, I decided do it with a class variable.
But still, the feeling that this is not very correct does not leave. What other options are there?
You can use self.get_queryset() inside the list method instead of using a class variable. The get_queryset method will be executed every time you call it, and it will return the current queryset so:
class SomeViewSet(mixins.ListModelMixin,
GenericViewSet):
def get_queryset(self):
return ... # some_logic
def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
response = super().list(request, *args, **kwargs)
response.data = {'count': queryset.count(),
'data': response.data}
return response
To avoid the issue of multiple database queries, you can make use of the queryset that is already retrieved by the ListModelMixin and stored in the response.data attribute so:
class SomeViewSet(mixins.ListModelMixin,
GenericViewSet):
def get_queryset(self):
return ... # some_logic
def list(self, request, *args, **kwargs):
response = super().list(request, *args, **kwargs)
queryset = response.data
response.data = {'count': len(queryset),
'data': queryset}
return response