startapp - python rest framework example
Python Django Rest Framework UnorderedObjectListWarning (5)
Déjame darte una respuesta actualizada a los nuevos desarrollos ...
https://code.djangoproject.com/ticket/6089
El orden predeterminado del modelo de
User
se ha eliminado en Django.
Si se encuentra en esta página debido a una actualización, es muy probable que esté conectado a este cambio.
Hay 2 versiones de este problema con las que podría estar lidiando.
-
su propio modelo no tiene un pedido predeterminado en su
Meta
(ver respuesta aceptada) - está utilizando un modelo de una aplicación que está utilizando como una dependencia que no tiene un pedido predeterminado
Dado que, literalmente, el modelo de
User
Django en sí no se adhiere a los pedidos, está muy claro que el segundo escenario no se puede resolver pidiendo a los encargados del mantenimiento de esas dependencias que realicen un pedido predeterminado.
De acuerdo, ahora debe anular el modelo que se está utilizando para lo que sea que esté haciendo (a veces es una buena idea, pero no es bueno para abordar un problema tan pequeño).
Entonces te queda abordarlo en el nivel de vista.
También desea hacer algo que funcione bien con cualquier clase de filtro de pedido que haya aplicado.
Para eso, establezca el parámetro de
ordering
la vista.
class Reviewers(ListView):
model = User
paginate_by = 50
ordering = [''username'']
Consulte también ¿Hay un modelo de vista de lista de Django?
Actualicé Django 1.10.4 a 1.11.1 y, de repente, recibo una tonelada de estos mensajes cuando ejecuto mis pruebas:
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)
Lo he rastreado hasta el módulo de paginación de Django: https://github.com/django/django/blob/master/django/core/paginator.py#L100
Parece estar relacionado con mi código de conjunto de consultas:
return get_user_model().objects.filter(id=self.request.user.id)
¿Cómo puedo encontrar más detalles sobre esta advertencia?
Parece ser que necesito agregar un
order_by(id)
al final de cada filtro, pero parece que no puedo encontrar qué código necesita el order_by agregado (porque la advertencia no devuelve un seguimiento de la pila y así sucede al azar durante mi prueba de funcionamiento).
¡Gracias!
Editar:
Entonces, usando @KlausD. consejo de verbosidad, miré una prueba que causa este error:
response = self.client.get(''/api/orders/'')
Esto va a
OrderViewSet
pero ninguna de las cosas en get_queryset lo causa y nada en la clase de serializador lo causa.
Tengo otras pruebas que usan el mismo código para obtener / api / orders y esas no lo causan ... ¿Qué hace DRF después de get_queryset?
https://github.com/encode/django-rest-framework/blob/master/rest_framework/pagination.py#L166
Si pongo un rastreo en la paginación, obtengo un montón de cosas relacionadas con django rest framework, pero nada que indique cuál de mis consultas está activando la advertencia de orden.
Entonces, para solucionar esto, tuve que encontrar todas las cláusulas
all
,
offset
,
filter
y
limit
y agregarles una cláusula
order_by
.
Algunos lo solucioné agregando un pedido predeterminado:
class Meta:
ordering = [''-id'']
En ViewSets para Django Rest Framework (app / apiviews.py) tuve que actualizar todos los métodos
get_queryset
ya que agregar un pedido predeterminado no parecía funcionar.
Espero que esto ayude a alguien más. :)
Incluyendo esto no funcionó para mí = (.
class Meta: ordering = [''-id'']
Pero trabajó cambiando get_queryset (self) y ordenando la lista con .order_by (''id'') . Tal vez funcionó porque estoy usando filtros, ahora no
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'')
Otra opción es agregar
OrderingFilter
http://www.django-rest-framework.org/api-guide/filtering/#orderingfilter
Recibí esta advertencia cuando utilicé objetos.todos () en mi view.py
profile_list = Profile.objects.all()
paginator = Paginator(profile_list, 25)
para arreglar esto cambié mi código a:
profile_list = Profile.objects.get_queryset().order_by(''id'')
paginator = Paginator(profile_list, 25)