Python Django Rest Framework 순서가 지정되지 않은 ObjectListWarning


88

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이 (추가 필요가있는 코드를 찾을 수 없습니다 및 운영).

감사!

편집하다:

따라서 @KlausD를 사용합니다. 자세한 정보,이 오류를 일으키는 테스트를 살펴 보았습니다.

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

이것은 이동 OrderViewSet하지만 get_queryset의 어떤 것도 원인이 아니며 serializer 클래스의 어떤 것도 원인이되지 않습니다. 동일한 코드를 사용하여 / api / orders를 가져 오는 다른 테스트가 있는데이 테스트가 발생하지 않습니다 .... get_queryset 후에 DRF가 수행하는 작업은 무엇입니까?

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

페이지 매김에 트레이스 백을 넣으면 django rest 프레임 워크와 관련된 모든 것을 얻지 만 어떤 쿼리가 주문 경고를 트리거 하는지를 가리키는 것은 없습니다.


1
일반적으로 경고를 유발하는 테스트 이름으로 쉽게 찾을 수 있습니다. ( -v 2대부분의 테스트
Klaus D.

감사합니다 @KlausD. 이것은 유용한 알림입니다.
Denise Mauldin

1
쿼리의 외모는 당신은하고있는 곳 offset하고 limit있지만order_by
집시

감사합니다 @gipsy. 나는 .... 그 중 하나를 가지고 있지 않습니다
데니스 Mauldin

답변:


138

그래서 내가 문제를 해결하기 위해 모든 찾아야했다 all, offset, filter,와 limit절을하고 추가 order_by그들에게 절을. 일부는 기본 순서를 추가하여 수정했습니다.

class Meta:
   ordering = ['-id']

Django Rest Framework (app / apiviews.py)의 ViewSets get_queryset에서 기본 순서를 추가하는 것이 작동하지 않는 것 같았 기 때문에 모든 메서드 를 업데이트 해야했습니다.

이것이 다른 사람에게 도움이되기를 바랍니다. :)


2
신난다, DRF는 <3도 주문에 대한 모델을 읽고 몰랐
아미르 Savand

내 모델에 기본 주문이 있지만 여전히이 경고가 표시됩니다.
Ariel

내 실수. 부모 클래스에서 순서를 지정했지만 docs에 설명 된대로 적절하게 하위 클래스를 지정하지 않고 Meta 속성을 재정의 했으며 자식 클래스의 Meta에서는 순서가 없으므로 부모의 값이 손실되었습니다.
Ariel

1
참고 그 추가 -ordering = ['-id']내림차순으로 주문 쿼리를.
엘론드는 모니카 지원

50

내 view.py에서 objects.all ()을 사용할 때이 경고를 받았습니다.

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

이 문제를 해결하기 위해 코드를 다음과 같이 변경했습니다.

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

1
나는 그것이해야한다고 생각 Profile.objects.all().order_by('id').. 그렇지 않으면 내가 얻을, 나를 위해 작동 그 이상AttributeError: type object 'Profile' has no attribute 'get_queryset'
radtek

9

새로운 개발에 대한 업데이트 된 답변을 드리겠습니다 ...

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

User모델 의 기본 순서는 Django에서 제거되었습니다. 업그레이드로 인해이 페이지를 찾은 경우이 변경 사항과 관련이있을 가능성이 큽니다.

이 문제에는 두 가지 버전이 있습니다.

  1. 자신의 모델에는 기본 순서가 없습니다 Meta(허용되는 답변 참조)
  2. 기본 순서가없는 종속성으로 사용중인 앱의 모델을 사용하고 있습니다.

말 그대로 Django User모델 자체가 순서를 따르지 않기 때문에 두 번째 시나리오는 이러한 종속성의 유지 관리자에게 기본 순서를 지정하도록 요청하여 해결할 수 없다는 것이 매우 분명합니다. 좋아, 이제 당신은 당신이하는 일에 사용되는 모델을 재정의해야한다 (때로는 좋은 생각이지만 그런 사소한 문제를 해결하기에는 좋지 않다).

따라서 뷰 수준에서 문제를 해결해야합니다. 또한 적용한 정렬 필터 클래스와 잘 어울리는 작업을 수행하고 싶습니다. 이를 위해 뷰의 ordering매개 변수를 설정합니다 .

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

또한 Django List View 모델 정렬이 있습니까?를 참조하십시오 .



1

제 경우 order_by('id')에는 ordering.

class IntakeCaseViewSet(viewsets.ModelViewSet):
    schema = None
    queryset = IntakeCase.objects.all().order_by('id')

0

대신 모델 메타 클래스를 업데이트하십시오.

class UsefulModel(models.Model):
    
    class Meta:
        ordering='-created' # for example

이전 에 AlanSE가 권고 한대로보기 속성 'ordering'에서 순서를 재정의 할 수 있습니다 .

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

-2

이것을 포함하는 것은 나를 위해 작동하지 않았습니다.

class Meta:
   ordering = ['-id']

그러나 get_queryset (self)를 변경 하고 .order_by ( 'id')로 목록을 정렬했습니다 . 필터를 사용하고 있기 때문에 효과가 있었는지 모르겠습니다.

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')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.