Django REST Framework: overriding get_queryset () sometimes returns twice the queryset

I made a small endpoint by adapting the DRF ReadOnlyModelViewSet

defined like this:

class MyApi(viewsets.ReadOnlyModelViewSet):

    queryset = []
    serializer_class = MySerializer

    def get_queryset(self):
        print 'Debug: I am starting...\n\n\n\n'
        # do a lot of things filtering data from Django models by some information on neo4j and saving data in the queryset...
        return self.queryset

      

When I call MyApi

via url, it returns results without any problem, but sometimes it returns the result twice !! This is very strange ... This is not a systematic error, but it only happens occasionally.

I am using a line print 'Debug: I am starting...\n\n\n\n'

in the Apache log to investigate the problem. When this doubling occurs, I read in the magazine:

Debug: I am starting...




Debug: I am starting...

      

Seems to be get_queryset

called more than once. It is very strange. I have not reported the details of the logic inside this method, I think the problem is elsewhere or is it a bug ... How can I solve?

+3


source to share


4 answers


You have defined queryset

as a class attribute.

class MyApi(viewsets.ReadOnlyModelViewSet):
    queryset = []

      

This means that every time you add to self.queryset

, you are adding to the same list. Your method get_queryset

is only called once, but it self.queryset

already contains entries at the beginning of the method. To see the problem in action, print self.queryset

in your method at the very beginning, before you change it.



You are better off doing something like:

class MyApi(viewsets.ReadOnlyModelViewSet):
    queryset = None  # this line is probably not required, but some code checking tools like it to be defined.

    def get_queryset(self):
        self.queryset = []
        ...
        return self.queryset

      

+5


source


If you are using a custom permission like DjangoModelPermissions . You need to check that the method of get_queryset

your View is not being called.

For example, DjangoModelPermissions calls this method here :

if hasattr(view, 'get_queryset'):
    queryset = view.get_queryset()
else:
    queryset = getattr(view, 'queryset', None)

      

If I use this permission the same as it does. The method get_queryset

will be called twice.



So, I changed it to this:

queryset = getattr(view, 'queryset', None)

      

As a result, it is simply called once. Hope this helps.

+1


source


Had the same issue and just ran the trackback Turns out the second run is the rest_framework render files calling view.get_queryset ().

Try calling it from the command line and then checking the results.

0


source


You define queryset = []

as class attributes and class attributes are "shared by all instances". So, if the python process adds some data to your attribute queryset

, subsequent view instances will only have that data if they are created by the same process.

0


source







All Articles