Подтвердить что ты не робот

Python Django Rest Framework UnorderedObjectListWarning

Я обновился с Django 1.10.4 до 1.11.1, и внезапно я получаю тонну этих сообщений, когда запускаю тесты:

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)

Я проследил это до модуля Django Pagination: https://github.com/django/django/blob/master/django/core/paginator.py#L100

Похоже, что это связано с кодом запроса:

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

Как я могу найти более подробную информацию об этом предупреждении? Кажется, что мне нужно добавить order_by(id) в конец каждого фильтра, но я не могу найти, какой код нужно добавить order_by (поскольку предупреждение не возвращает трассировку стека, и поэтому это происходит случайно во время моего пробного прогона).

Спасибо!

Edit:

Таким образом, используя @KlausD. verbosity tip, я посмотрел на тест, вызвавший эту ошибку:

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

Это относится к OrderViewSet, но ни одна из вещей в get_queryset не вызывает этого, и ничто в классе serializer не вызывает этого. У меня есть другие тесты, которые используют один и тот же код для получения /api/orders, и это не вызывает его.... Что делает DRF после get_queryset?

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

Если я помещу трассировку в разбивку на страницы, я получаю целую кучу вещей, связанных с фреймворком django rest, но ничего, что указывает на то, какие из моих запросов запускают предупреждение о заказе.

4b9b3361

Ответ 1

Итак, чтобы исправить это, мне пришлось найти все предложения all, offset, filter и limit и добавить к ним предложение order_by. Некоторые исправления добавляются по умолчанию:

class Meta:
   ordering = ['-id']

В представлении ViewSets для Django Rest Framework (app/apiviews.py) мне пришлось обновить все методы get_queryset, поскольку добавление по умолчанию заказа не работало.

Надеюсь, это поможет кому-то другому.:)

Ответ 2

Я получал это предупреждение, когда я использовал объекты object.all() в моей view.py

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

чтобы исправить это, я изменил свой код на:

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

Ответ 4

Позвольте мне дать ответ в курсе новых событий...

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

Порядок по умолчанию для модели User был удален в Django. Если вы оказались на этой странице из-за обновления, скорее всего, это связано с этим изменением.

Есть 2 версии этой проблемы, с которыми вы можете иметь дело.

  1. Ваша собственная модель не имеет порядка по умолчанию в своей Meta (см. принятый ответ)
  2. вы используете модель из приложения, которое вы используете в качестве зависимости, которая не имеет порядка по умолчанию

Поскольку буквально сама модель User Django не придерживается порядка, очень ясно, что второй сценарий не может быть решен, если попросить сопровождающих этих зависимостей установить порядок по умолчанию. Итак, теперь вы должны либо переопределить модель, используемую для любых ваших действий (иногда это хорошая идея, но не подходит для решения такой незначительной проблемы).

Таким образом, вы остались с адресацией на уровне просмотра. Вы также хотите сделать что-то, что будет хорошо работать с любым классом фильтра упорядочения, который вы применили. Для этого установите параметр ordering просмотра.

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

Также смотрите Сортировка модели Django List View?