131 votes

Cadre de repos Python Django UnorderedObjectListWarning

J'ai effectué une mise à niveau de Django 1.10.4 vers 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)

Je suis remonté jusqu'au module Django Pagination : https://github.com/django/django/blob/master/django/core/paginator.py#L100

Il semble que cela soit lié à mon code queryset :

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

Comment puis-je trouver plus de détails sur cet avertissement ? Il semblerait que je doive ajouter un fichier order_by(id) à la fin de chaque filtre, mais je n'arrive pas à trouver quel code a besoin de l'ajout de order_by (parce que l'avertissement ne renvoie pas de trace de la pile et qu'il se produit de manière aléatoire pendant mon test).

Gracias.

Edit :

Donc en utilisant l'astuce de verbosité de @KlausD., j'ai regardé un test causant 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 serializer ne le cause. J'ai d'autres tests qui utilisent le même code pour obtenir /api/orders et ceux-ci ne le provoquent pas..... Que fait la DRF après get_queryset ?

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

Si je mets une traceback dans la pagination, j'obtiens tout un tas de choses liées au django rest framework mais rien qui permette de savoir laquelle de mes requêtes déclenche l'avertissement de commande.

1 votes

En général, il devrait être facile à trouver par le nom du test qui cause l'avertissement. Vous pouvez vouloir exécuter les tests avec de la verbosité ( -v 2 sur la plupart des exécutants de test)

0 votes

Merci @KlausD. C'est un rappel utile.

1 votes

Recherche les requêtes où vous faites un offset y limit mais non order_by

2voto

Malinoski Points 19

Inclure cela n'a pas fonctionné pour moi.

class Meta:
   ordering = ['-id']

Mais changer get_queryset(self) et de trier la liste avec .order_by('id') a fait. Ça a peut-être marché parce que j'utilise des filtres, je ne sais pas.

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')

1voto

Ahmed Shehab Points 796

Mettez à jour la méta-classe du modèle à la place.

class UsefulModel(models.Model):

    class Meta:
        ordering='-created' # for example

vous pouvez toujours remplacer l'ordre de classement à partir de l'attribut de vue "ordering" Comme conseillé par AlanSE précédemment.

class UsefulView(ListView):
    ordering = ['-created']

0voto

SanRaph Points 141

Dans mon cas, il s'agissait d'un tuple et ce tuple doit contenir une virgule même si vous n'analysez qu'un seul élément.

     class Meta:
      ordering = ('-name',)

-1voto

Alex Pashkov Points 11

Le moyen le plus simple de résoudre ce problème est d'ajouter un champ "tri par défaut" (nommé "ordering") à la classe META du modèle. Par exemple :

class Device(DeleteMixin, UpdateFieldsMixin):
    device_id = models.CharField(max_length=150, unique=True, verbose_name='title')

    class Meta:
        ordering = ['-pk']

Dans mon cas, c'était : ......F........../home/my_test_project/.venv/lib/python3.6/site-packages/rest_framework/pagination.py:200 : UnorderedObjectListWarning : La pagination peut donner des résultats incohérents avec une liste d'objets non ordonnée : <class 'device.models.device.Device'> QuerySet. paginator = self.django_paginator_class(queryset, page_size) .......

Est devenu : ......F.............................

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X