I made a little endpoint, adapting DRF ReadOnlyModelViewSet
, defined as follows:
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 problems, but sometimes it returns doubled result!! It's very strange...It's not a systematic error but happens only sometimes.
I use the line print 'Debug: I am starting...\n\n\n\n'
in Apache log to investigate the problem. When that doubling happens, I read in the log:
Debug: I am starting...
Debug: I am starting...
It seems like get_queryset
is called more than one time. It's very strange. I didn't report the detail of the logic inside that method, I think the problem is elsewhere or that is a bug...How can I solve?
You have defined queryset
as a class attribute.
class MyApi(viewsets.ReadOnlyModelViewSet):
queryset = []
That means that each time you append to self.queryset
, you are appending to the same list. Your get_queryset
method is only called once, but self.queryset
already has entries in it 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 would be better to do 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
If you are using a custom permission like DjangoModelPermissions. You need to check that the get_queryset
method of your View is not being called.
For example, DjangoModelPermissions call this method here:
if hasattr(view, 'get_queryset'):
queryset = view.get_queryset()
else:
queryset = getattr(view, 'queryset', None)
If I use this permission just as it is. The method get_queryset
will be called twice.
So I changed it to just this:
queryset = getattr(view, 'queryset', None)
As a result it is just called once. Hope this helps.
You are defining queryset = []
as class attributes and class attributes are "shared by all instances". So, if you python process append some data to your queryset
attribute, the subsequent view instances would have that data, only if they are created by the same process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With