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フレームワークに関連するものが大量に得られますが、どのクエリが注文警告をトリガーしているかを示すものは何もありません。
そのため、これを修正するには、all
、offset
、filter
、およびlimit
のすべての句を見つけて、order_by
句を追加する必要がありました。デフォルトの順序を追加して修正したもの:
class Meta:
ordering = ['-id']
Django Rest Framework(app/apiviews.py)のViewSetsでは、デフォルトの順序を追加しても機能しないように思えたため、get_queryset
メソッドをすべて更新する必要がありました。
これが他の誰かに役立つことを願っています。 :)
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)
別のオプションはOrderingFilter
を追加することです
http://www.Django-rest-framework.org/api-guide/filtering/#orderingfilter
新しい開発に更新された答えを教えてください...
https://code.djangoproject.com/ticket/6089
User
モデルのデフォルトの順序はDjangoで削除されました。アップグレードのためにこのページで自分自身を見つけた場合、この変更に関連している可能性が非常に高いです。
この問題には2つのバージョンがあります。
Meta
にはデフォルトの順序がありません(受け入れられた回答を参照)文字通りDjango User
モデル自体は順序付けに準拠していないため、これらの依存関係のメンテナーにデフォルトの順序付けを依頼することで2番目のシナリオを解決できないことは非常に明確です。わかりましたので、今はあなたがしていることのために使われているモデルをオーバーライドする必要があります(時には良いアイデアですが、そのような小さな問題に対処するのは良くありません)。
したがって、ビューレベルでアドレス指定する必要があります。また、適用した順序付けフィルタークラスで適切に動作する何かを実行したい場合もあります。そのためには、ビューのordering
パラメーターを設定します。
class Reviewers(ListView):
model = User
paginate_by = 50
ordering = ['username']
Djangoリストビューモデルのソートはありますか? も参照してください。