Django REST框架:重写get_queryset()有时会返回一个doubled查询集

时间:2015-08-04 12:32:24

标签: python django django-rest-framework

我做了一个小端点,调整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

当我通过URL调用MyApi时,它返回结果没有任何问题,但有时会返回doubled结果!!这很奇怪......这不是一个系统错误,而只是偶尔发生。

我在Apache日志中使用行print 'Debug: I am starting...\n\n\n\n'来调查问题。当这个加倍发生时,我在日志中读到:

Debug: I am starting...




Debug: I am starting...

似乎get_queryset不止一次被召唤。这很奇怪。我没有报告该方法中的逻辑细节,我认为问题出在其他地方或者是一个错误...我该如何解决?

4 个答案:

答案 0 :(得分:5)

您已将queryset定义为类属性。

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

这意味着每次追加到self.queryset时,您都会附加到同一列表中。您的get_queryset方法只调用一次,但self.queryset在方法开头已有条目。

:在您开始修改方法时,首先在方法中查看问题print self.queryset

你最好做点什么:

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

答案 1 :(得分:1)

如果您使用的是 DjangoModelPermissions 等自定义权限。您需要检查是否未调用查看get_queryset方法。

例如,DjangoModelPermissions调用此方法here

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

如果我原样使用此权限。方法get_queryset将被调用两次。

所以我把它改成了这个:

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

结果它只被调用一次。希望这会有所帮助。

答案 2 :(得分:0)

遇到同样的问题,只是跑了一个引用 事实证明,第二次运行是rest_framework的渲染文件,调用view.get_queryset()。

尝试从命令行调用它,然后检查结果。

答案 3 :(得分:0)

您正在定义queryset = []作为类属性,类属性由所有实例共享"。因此,如果python进程将一些数据附加到queryset属性,则后续视图实例将具有该数据,只有它们是由同一进程创建的。