简体   繁体   English

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

[英]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. 您需要检查是否未调用Viewget_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.

相关问题 Django REST Framework - 从 get_queryset 返回一个值? - Django REST Framework - return a value from get_queryset? 如何在 Django Rest Framework 中使用 get_queryset 进行过滤? - How to filter using get_queryset in Django Rest Framework? Django rest 壮观 - 自定义 get_queryset() - Django rest spectacular - Customizing get_queryset() Django 其余框架视图集 get_queryset() 不返回正确的查询集 - Django rest framework viewset get_queryset() doesn't return correct queryset Django Rest Framework错误无法在未设置`.queryset`或没有`.get_queryset()`方法的视图上应用DjangoModelPermissions - django rest framework error Cannot apply DjangoModelPermissions on a view that does not set `.queryset` or have a `.get_queryset()` method Django rest 框架,应该能够覆盖 get_queryset 而不是定义 queryset 属性吗? - Django rest framework, should be able to override get_queryset and not define queryset attribute? Django:重写get_queryset()时如何注入数据? - Django: how to inject data when overriding get_queryset()? Django Dry方法获取get_queryset - Django Dry approach to get_queryset Django:get_queryset(self)中的条件表达式 - Django : Conditional expressions in get_queryset(self) LoginRequiredMixin 和 get_queryset 与 django-tables2 - LoginRequiredMixin and get_queryset with django-tables2
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM