Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewSet class variable

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?

like image 448
Anonymous Wizard Avatar asked May 26 '26 19:05

Anonymous Wizard


1 Answers

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

Edit:

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
like image 135
Sunderam Dubey Avatar answered May 28 '26 07:05

Sunderam Dubey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!