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?
source to share
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
source to share
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.
source to share