[英]Django REST Framework: overriding get_queryset() sometimes returns a doubled queryset
I made a little endpoint, adapting DRF ReadOnlyModelViewSet
, defined as follows: 我做了一个小端点,适应DRF
ReadOnlyModelViewSet
,定义如下:
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!! 当我通过URL调用
MyApi
,它返回结果没有任何问题,但有时它会返回doubled结果!! 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. 我使用行
print 'Debug: I am starting...\\n\\n\\n\\n'
在Apache日志中print 'Debug: I am starting...\\n\\n\\n\\n'
来调查问题。 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. 好像
get_queryset
被调用了get_queryset
。 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. 您已将
queryset
定义为类属性。
class MyApi(viewsets.ReadOnlyModelViewSet):
queryset = []
That means that each time you append to self.queryset
, you are appending to the same list. 这意味着每次附加到
self.queryset
,您都会附加到同一列表中。 Your get_queryset
method is only called once, but self.queryset
already has entries in it at the beginning of the method. 你的
get_queryset
方法只被调用一次,但是self.queryset
在方法的开头已经有了条目。 To see the problem in action, print self.queryset
in your method at the very beginning, before you change it. 要查看操作中的问题,请在更改之前在方法中
print self.queryset
。
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 . 如果您正在使用DjangoModelPermissions等自定义权限。 You need to check that the
get_queryset
method of your View is not being called. 您需要检查是否未调用View的
get_queryset
方法。
For example, DjangoModelPermissions call this method here : 例如, DjangoModelPermissions 在这里调用此方法:
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. get_queryset
方法将被调用两次。
So I changed it to just this: 所以我把它改成了这个:
queryset = getattr(view, 'queryset', None)
As a result it is just called once. 结果它只被调用一次。 Hope this helps.
希望这可以帮助。
Had the same problem and just ran a trackback Turns out that the second run is the rest_framework's rendering files calling view.get_queryset(). 有同样的问题,只是跑了一个引用结果证明第二次运行是rest_framework的渲染文件调用view.get_queryset()。
Try calling it from the command line and then checking the results. 尝试从命令行调用它,然后检查结果。
You are defining queryset = []
as class attributes and class attributes are "shared by all instances". 您将
queryset = []
定义为类属性,类属性“由所有实例共享”。 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. 因此,如果python进程将一些数据附加到
queryset
属性,则后续视图实例将具有该数据,只有它们是由同一进程创建的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.