Je suis passé de Django 1.10.4 à 1.11.1 et tout à coup, je reçois une tonne de ces messages lorsque je lance mes tests:
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)
J'ai retracé cela jusqu'au Django Module de pagination: https://github.com/Django/django/blob/master/Django/core/paginator.py#L10
Cela semble lié à mon code de requête:
return get_user_model().objects.filter(id=self.request.user.id)
Comment puis-je trouver plus de détails sur cet avertissement? Il semble que j’ai besoin d’ajouter un order_by(id)
à la fin de chaque filtre, mais je n'arrive pas à trouver quel code a besoin de order_by (car l’avertissement ne renvoie pas de trace de pile et donc cela se produit de manière aléatoire pendant mon test).
Merci!
Modifier:
Donc, en utilisant @ KlausD. Astuce de verbosité, j'ai regardé un test provoquant cette erreur:
response = self.client.get('/api/orders/')
Ceci va à OrderViewSet
mais aucune des choses dans get_queryset ne le cause et rien dans la classe sérialiseur ne le cause. J'ai d'autres tests qui utilisent le même code pour obtenir/api/orders et ceux-ci ne le causent pas .... Que fait DRF après get_queryset?
https://github.com/encode/Django-rest-framework/blob/master/rest_framework/pagination.py#L166
Si je mets une trace dans la pagination, je reçois une foule de choses liées au cadre de repos Django), mais rien qui pointe vers lequel de mes requêtes déclenche l'avertissement d'ordre.
Donc, pour résoudre ce problème, je devais trouver toutes les clauses all
, offset
, filter
et limit
et ajouter un order_by
clause à eux. Certains j'ai corrigé en ajoutant une commande par défaut:
class Meta:
ordering = ['-id']
Dans les ViewSets pour Django Rest Framework (app/apiviews.py), je devais mettre à jour tous les get_queryset
méthodes comme l'ajout d'un ordre par défaut ne semble pas fonctionner.
J'espère que ceci aide quelqu'un d'autre. :)
Je recevais cet avertissement lorsque j'ai utilisé objects.all () dans mon view.py
profile_list = Profile.objects.all()
paginator = Paginator(profile_list, 25)
pour résoudre ce problème, j'ai changé mon code en:
profile_list = Profile.objects.get_queryset().order_by('id')
paginator = Paginator(profile_list, 25)
Une autre option consiste à ajouter OrderingFilter
http://www.Django-rest-framework.org/api-guide/filtering/#orderingfilter
Permettez-moi de donner une réponse mise à jour aux nouveaux développements ...
https://code.djangoproject.com/ticket/6089
L'ordre par défaut du modèle User
a été supprimé de Django. Si vous vous êtes retrouvé sur cette page à cause d'une mise à niveau, il est très probablement lié à ce changement.
Il existe 2 versions de ce problème que vous pourriez traiter.
Meta
(voir la réponse acceptée)Etant donné que le modèle Django User
lui-même ne respecte pas les commandes, il est très clair que le second scénario ne peut pas être résolu en demandant aux responsables de ces dépendances de définir des commandes par défaut. Alors, maintenant, vous devez soit remplacer le modèle utilisé pour quoi que vous fassiez (parfois une bonne idée, mais ce n’est pas bon pour traiter un problème aussi mineur).
Il ne vous reste donc plus qu'à vous en occuper au niveau de la vue. Vous voulez également faire quelque chose qui fonctionnera bien avec n'importe quelle classe de filtre de classement que vous aurez appliquée. Pour cela, définissez le paramètre ordering
de la vue.
class Reviewers(ListView):
model = User
paginate_by = 50
ordering = ['username']
Voir aussi Existe-t-il Django Tri par modèle de vue?