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