Zaktualizowałem Django z wersji 1.10.4 do 1.11.1 i nagle otrzymuję mnóstwo takich komunikatów, gdy uruchamiam testy:
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)
Prześledziłem to z powrotem do modułu paginacji Django: https://github.com/django/django/blob/master/django/core/paginator.py#L100
Wydaje się, że jest to związane z kodem mojego zestawu zapytań:
return get_user_model().objects.filter(id=self.request.user.id)
Jak mogę znaleźć więcej szczegółów na temat tego ostrzeżenia? Wygląda na to, że muszę dodać order_by(id)
na końcu każdego filtru, ale nie mogę znaleźć kodu, który wymaga dodania polecenia order_by (ponieważ ostrzeżenie nie zwraca śladu stosu i dzieje się to losowo podczas mojego testu biegać).
Dzięki!
Edytować:
Więc używając @KlausD. szczegółowość wskazówka, spojrzałem na test powodujący ten błąd:
response = self.client.get('/api/orders/')
To idzie, OrderViewSet
ale żadna z rzeczy w get_queryset nie powoduje tego i nic w klasie serializatora nie powoduje tego. Mam inne testy, które używają tego samego kodu do pobierania / api / zamówień i nie powodują tego… Co robi DRF po get_queryset?
https://github.com/encode/django-rest-framework/blob/master/rest_framework/pagination.py#L166
Jeśli wstawię śledzenie do paginacji, otrzymam całą masę rzeczy związanych z frameworkiem django rest, ale nic, co wskazuje, które z moich zapytań wyzwala ostrzeżenie o zamówieniu.
źródło
-v 2
na większości testerów)offset
alimit
jednak nieorder_by
Odpowiedzi:
Tak więc w celu ustalenia tego musiałem znaleźć wszystkie
all
,offset
,filter
orazlimit
klauzule i dodaćorder_by
klauzulę do nich. Niektóre naprawiłem, dodając domyślną kolejność:class Meta: ordering = ['-id']
W ViewSets for Django Rest Framework (app / apiviews.py) musiałem zaktualizować wszystkie
get_queryset
metody, ponieważ dodanie domyślnej kolejności nie działało.Mam nadzieję, że to pomoże komuś innemu. :)
źródło
-
wordering = ['-id']
zamówieniach zapytania w porządku malejącym.Otrzymałem to ostrzeżenie, gdy użyłem objects.all () w moim view.py
profile_list = Profile.objects.all() paginator = Paginator(profile_list, 25)
aby to naprawić, zmieniłem kod na:
profile_list = Profile.objects.get_queryset().order_by('id') paginator = Paginator(profile_list, 25)
źródło
Profile.objects.all().order_by('id')
.. przynajmniej to działa u mnie inaczej dostajęAttributeError: type object 'Profile' has no attribute 'get_queryset'
Pozwólcie, że udzielę odpowiedzi zaktualizowanej o nowe osiągnięcia ...
https://code.djangoproject.com/ticket/6089
Domyślna kolejność
User
modelu została usunięta w Django. Jeśli znalazłeś się na tej stronie z powodu aktualizacji, najprawdopodobniej jest to związane z tą zmianą.Istnieją 2 wersje tego problemu, z którymi możesz mieć do czynienia.
Meta
(patrz zaakceptowana odpowiedź)Ponieważ dosłownie
User
sam model Django nie przestrzega kolejności, jest bardzo jasne, że drugiego scenariusza nie można rozwiązać, prosząc opiekunów tych zależności o ustawienie domyślnej kolejności. Okay, więc teraz albo musisz zastąpić model używany do wszystkiego, co robisz (czasami jest to dobry pomysł, ale nie jest dobry do rozwiązania tak drobnego problemu).Pozostaje więc rozwiązanie tego problemu na poziomie widoku. Chcesz także zrobić coś, co będzie dobrze pasować do każdej zastosowanej klasy filtru porządkowania. W tym celu ustaw
ordering
parametr widoku .class Reviewers(ListView): model = User paginate_by = 50 ordering = ['username']
Zobacz także Czy istnieje sortowanie modeli w widoku listy Django?
źródło
Inną opcją jest dodanie
OrderingFilter
http://www.django-rest-framework.org/api-guide/filtering/#orderingfilter
źródło
W moim przypadku
order_by('id')
zamiast tego musiałem dodaćordering
.class IntakeCaseViewSet(viewsets.ModelViewSet): schema = None queryset = IntakeCase.objects.all().order_by('id')
źródło
Zaktualizuj zamiast tego klasę meta modelu.
class UsefulModel(models.Model): class Meta: ordering='-created' # for example
nadal możesz zmienić kolejność w atrybucie „ordering” widoku „ordering”. Zgodnie z wcześniejszymi zaleceniami AlanSE .
class UsefulView(ListView): ordering = ['-created']
źródło
W tym to nie zadziałało dla mnie.
class Meta: ordering = ['-id']
Ale zmiana get_queryset (self) i posortowanie listy za pomocą .order_by ('id') zrobiło. Może zadziałało, ponieważ używam filtrów, nie wiem
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')
źródło