Python Django Rest Framework UnorderedObjectListWarning

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44033670/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 23:39:07  来源:igfitidea点击:

Python Django Rest Framework UnorderedObjectListWarning

pythondjangodjango-rest-framework

提问by Denise Mauldin

I upgraded from Django 1.10.4 to 1.11.1 and all of a sudden I'm getting a ton of these messages when I run my tests:

我从 Django 1.10.4 升级到 1.11.1,突然间我在运行测试时收到了大量这些消息:

lib/python3.5/site-packages/rest_framework/pagination.py:208:
UnorderedObjectListWarning: 
Pagination may yield inconsistent results with an unordered object_list: 
<QuerySet [<Group: Requester>]>
paginator = self.django_paginator_class(queryset, page_size)

I've traced that back to the Django Pagination module: https://github.com/django/django/blob/master/django/core/paginator.py#L100

我已经追溯到 Django 分页模块:https: //github.com/django/django/blob/master/django/core/paginator.py#L100

It seems to be related to my queryset code:

它似乎与我的查询集代码有关:

return get_user_model().objects.filter(id=self.request.user.id)

How can I find more details on this warning? It seems to be that I need to add a order_by(id)on the end of every filter, but I can't seem to find which code needs the order_by added (because the warning doesn't return a stack trace and so it happens randomly during my test run).

如何找到有关此警告的更多详细信息?似乎我需要order_by(id)在每个过滤器的末尾添加一个,但我似乎无法找到需要添加 order_by 的代码(因为警告不返回堆栈跟踪,因此它在我的测试过程中随机发生跑)。

Thanks!

谢谢!

Edit:

编辑:

So by using @KlausD. verbosity tip, I looked at a test causing this error:

所以通过使用@KlausD。详细提示,我查看了导致此错误的测试:

response = self.client.get('/api/orders/')

response = self.client.get('/api/orders/')

This goes to OrderViewSetbut none of the things in get_queryset cause it and nothing in serializer class causes it. I have other tests that use the same code to get /api/orders and those don't cause it.... What does DRF do after get_queryset?

这会发生,OrderViewSet但 get_queryset 中的任何事情都不会导致它,并且序列化程序类中的任何东西都不会导致它。我有其他测试使用相同的代码来获取 /api/orders 并且那些不会导致它......在 get_queryset 之后 DRF 做什么?

https://github.com/encode/django-rest-framework/blob/master/rest_framework/pagination.py#L166

https://github.com/encode/django-rest-framework/blob/master/rest_framework/pagination.py#L166

If I put a traceback into pagination then I get a whole bunch of stuff related to django rest framework but nothing that points back to which of my queries is triggering the order warning.

如果我将回溯放入分页,那么我会得到一大堆与 django rest 框架相关的东西,但没有任何东西可以指向我的哪个查询触发了订单警告。

回答by Denise Mauldin

So in order to fix this I had to find all of the all, offset, filter, and limitclauses and add a order_byclause to them. Some I fixed by adding a default ordering:

因此,为了解决这个问题我必须找到所有的alloffsetfilter,以及limit条款和补充order_by条款给他们。我通过添加默认顺序修复了一些问题:

class Meta:
   ordering = ['-id']

In the ViewSets for Django Rest Framework (app/apiviews.py) I had to update all of the get_querysetmethods as adding a default ordering didn't seem to work.

在 Django Rest Framework (app/apiviews.py) 的 ViewSets 中,我必须更新所有get_queryset方法,因为添加默认排序似乎不起作用。

Hope this helps someone else. :)

希望这对其他人有帮助。:)

回答by Rajiv Sharma

I was getting this warning when i used objects.all() in my view.py

当我在 view.py 中使用 objects.all() 时收到此警告

profile_list = Profile.objects.all()
paginator = Paginator(profile_list, 25)

to fix this i changed my code to :

为了解决这个问题,我将代码更改为:

profile_list = Profile.objects.get_queryset().order_by('id')
paginator = Paginator(profile_list, 25)

回答by AlanSE

Let me give an answer updated to new developments...

让我根据新的发展给出一个更新的答案......

https://code.djangoproject.com/ticket/6089

https://code.djangoproject.com/ticket/6089

The default ordering of the Usermodel has been removed in Django. If you found yourself at this page because of an upgrade, it's very likely connected to this change.

User模型的默认排序已在 Django 中删除。如果您因为升级而出现在此页面,则很可能与此更改有关。

There are 2 versions of this problem you might be dealing with.

您可能正在处理这个问题的 2 个版本。

  1. your own model does not have a default ordering in its Meta(see accepted answer)
  2. you are using a model from an app you are using as a dependency which does not have a default ordering
  1. 您自己的模型中没有默认排序Meta(请参阅已接受的答案)
  2. 您正在使用来自您用作依赖项的应用程序的模型,该模型没有默认排序

Since literally the Django Usermodel itself does not adhere to ordering, it's very clear that the second scenario cannot be resolved by asking the maintainers of those dependencies to put in a default ordering. Okay, so now you either have to override the model being used for whatever your doing (sometimes a good idea, but not good for addressing such a minor issue).

由于从字面上看 DjangoUser模型本身并不遵循顺序,很明显,通过要求这些依赖项的维护者设置默认顺序无法解决第二种情况。好的,所以现在您要么必须覆盖用于您所做的任何事情的模型(有时是个好主意,但不适合解决这样一个小问题)。

So you're left with addressing it on the view level. You also want to do something that will play nicely with any ordering filter class you have applied. For that, set the view's orderingparameter.

因此,您只能在视图级别解决它。您还希望做一些可以与您应用的任何排序过滤器类很好地配合的事情。为此,设置视图的ordering参数。

class Reviewers(ListView):
    model = User
    paginate_by = 50
    ordering = ['username']

Also see Is there Django List View model sort?

另请参阅是否有 Django 列表视图模型排序?

回答by Michael Benin

回答by Malinoski

Including this didn't work for me.

包括这对我不起作用。

class Meta:
   ordering = ['-id']

But changing get_queryset(self)and sorting the list with .order_by('id')did. Maybe worked because I'm using filters, I don't know

但是更改get_queryset(self)并使用.order_by('id')对列表进行排序。可能有用,因为我使用了过滤器,我不知道

class MyView(viewsets.ModelViewSet):
    queryset = MyModel.objects.all()
    serializer_class = MySerializerSerializer

    def get_queryset(self):
        user = self.request.user
        return MyModel.objects.filter(owner=user).order_by('id')