web-dev-qa-db-ger.com

Python Django Rest Framework UnorderedObjectListWarning

Ich habe ein Upgrade von Django 1.10.4 auf 1.11.1 durchgeführt und plötzlich erhalte ich eine Menge dieser Meldungen, wenn ich meine Tests durchführe:

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)

Ich habe dies auf das Django= Paginierungsmodul zurückgeführt: https://github.com/Django/django/blob/master/Django/core/paginator.py#L10

Es scheint mit meinem QuerySet-Code zu tun zu haben:

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

Wie finde ich weitere Details zu dieser Warnung? Es scheint, dass ich am Ende jedes Filters eine order_by(id) hinzufügen muss, aber ich kann scheinbar nicht herausfinden, welcher Code die order_by benötigt, die hinzugefügt wird (weil die Warnung keinen Stack-Trace zurückgibt und) so passiert es zufällig während meines Testlaufs).

Vielen Dank!

Bearbeiten:

Also mit @KlausD. Tipp zur Ausführlichkeit, ich habe mir einen Test angesehen, der diesen Fehler verursacht:

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

Dies geht an OrderViewSet, aber keines der Dinge in get_queryset verursacht es und nichts in der Serializer-Klasse verursacht es. Ich habe andere Tests, die den gleichen Code verwenden, um/api/orders zu erhalten, und die verursachen es nicht .... Was macht DRF nach get_queryset?

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

Wenn ich die Paginierung zurückverfolge, erhalte ich eine ganze Reihe von Inhalten, die mit dem Django rest framework zusammenhängen, aber nichts, das darauf hinweist, welche meiner Abfragen die Bestellwarnung auslösen.

57
Denise Mauldin

Um dies zu beheben, musste ich alle Klauseln all, offset, filter und limit finden und eine order_by Klausel an sie. Einige habe ich durch Hinzufügen einer Standardbestellung behoben:

class Meta:
   ordering = ['-id']

In den ViewSets für Django Rest Framework (app/apiviews.py) musste ich alle get_queryset Methoden wie das Hinzufügen einer Standardbestellung schienen nicht zu funktionieren.

Hoffe das hilft jemand anderem. :)

83
Denise Mauldin

Ich habe diese Warnung erhalten, als ich objects.all () in my view.py verwendet habe

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

um dies zu beheben, änderte ich meinen Code auf:

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

Eine andere Option ist das Hinzufügen von OrderingFilter

http://www.Django-rest-framework.org/api-guide/filtering/#orderingfilter

3
Michael Benin

Lassen Sie mich eine aktualisierte Antwort auf neue Entwicklungen geben ...

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

Die Standardreihenfolge des Modells User wurde in Django entfernt. Wenn Sie sich aufgrund eines Upgrades auf dieser Seite befunden haben, hängt dies höchstwahrscheinlich mit dieser Änderung zusammen.

Es gibt 2 Versionen dieses Problems, mit denen Sie möglicherweise zu tun haben.

  1. ihr eigenes Modell hat keine Standardbestellung in seinem Meta (siehe akzeptierte Antwort)
  2. sie verwenden ein Modell aus einer App, die Sie als Abhängigkeit verwenden, für die keine Standardreihenfolge festgelegt ist

Da das Django User -Modell selbst nicht an der Reihenfolge festhält, ist es sehr klar, dass das zweite Szenario nicht gelöst werden kann, indem die Betreuer dieser Abhängigkeiten aufgefordert werden, eine Standardreihenfolge einzugeben Okay, jetzt müssen Sie entweder das Modell, das für Ihre Zwecke verwendet wird, außer Kraft setzen (manchmal eine gute Idee, aber nicht gut, um ein so kleines Problem anzugehen).

Sie müssen es also auf der Ansichtsebene ansprechen. Sie möchten auch etwas tun, das mit jeder von Ihnen angewendeten Sortierfilterklasse gut funktioniert. Setzen Sie dazu den Parameter ordering der Ansicht.

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

Siehe auch Gibt es Django List View Model Sort?

1
AlanSE