web-dev-qa-db-ja.com

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ページネーションモジュールにまでさかのぼりました: https://github.com/Django/django/blob/master/Django/core/paginator.py#L1

それは私のクエリセットコードに関連しているようです:

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にあるものはどれもそれを引き起こさず、シリアライザークラスには何も引き起こしません。/api/ordersを取得するために同じコードを使用する他のテストがあり、それらはそれを引き起こしません.... DRFはget_querysetの後に何をしますか?

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

ページネーションにトレースバックを設定すると、Django restフレームワークに関連するものが大量に得られますが、どのクエリが注文警告をトリガーしているかを示すものは何もありません。

57
Denise Mauldin

そのため、これを修正するには、alloffsetfilter、およびlimitのすべての句を見つけて、order_by句を追加する必要がありました。デフォルトの順序を追加して修正したもの:

class Meta:
   ordering = ['-id']

Django Rest Framework(app/apiviews.py)のViewSetsでは、デフォルトの順序を追加しても機能しないように思えたため、get_querysetメソッドをすべて更新する必要がありました。

これが他の誰かに役立つことを願っています。 :)

83
Denise Mauldin

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)
29
Rajiv Sharma

別のオプションはOrderingFilterを追加することです

http://www.Django-rest-framework.org/api-guide/filtering/#orderingfilter

3
Michael Benin

新しい開発に更新された答えを教えてください...

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

Userモデルのデフォルトの順序はDjangoで削除されました。アップグレードのためにこのページで自分自身を見つけた場合、この変更に関連している可能性が非常に高いです。

この問題には2つのバージョンがあります。

  1. 独自のモデルのMetaにはデフォルトの順序がありません(受け入れられた回答を参照)
  2. デフォルトの順序を持​​たない依存関係として使用しているアプリのモデルを使用している

文字通りDjango Userモデル自体は順序付けに準拠していないため、これらの依存関係のメンテナーにデフォルトの順序付けを依頼することで2番目のシナリオを解決できないことは非常に明確です。わかりましたので、今はあなたがしていることのために使われているモデルをオーバーライドする必要があります(時には良いアイデアですが、そのような小さな問題に対処するのは良くありません)。

したがって、ビューレベルでアドレス指定する必要があります。また、適用した順序付けフィルタークラスで適切に動作する何かを実行したい場合もあります。そのためには、ビューのorderingパラメーターを設定します。

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

Djangoリストビューモデルのソートはありますか? も参照してください。

1
AlanSE