11

コメントモデルの任意のフィールドでdistinct()を実行すると、常にすべてのレコードが返されます。

Comment.objects.values('user')。distinct()

[{'user':1}、{'user':0}、{'user':0}、{'user':0}、{'user':0}、{'user':1}、{ 'user':1}、{'user':1}、{'user':1}]

Comment.objects.values('ip_address')。distinct()

[{'ip_address':u'127.0.0.1'}、{' ip_address':u'192.168.0.180'}、{'ip_address':u'192.168.0.180'}、{' ip_address':u'192.168.0.180 '}、{' ip_address':u'192.168.0。180'}、{' ip_address':u'192.168.0.180'}、{'ip_address':u'192.168.0.180'}、{' ip_address':u'192.168.0.180'}、{'ip_address':u ' 192.168.0.180'}]

なぜこうなった?これを回避する方法はありますか?ありがとう!

ps:distinct()は、テスト中にカスタムモデルのさまざまなタイプのフィールドで非常にうまく実行されます。コメントフレームワークについて何か特別なことはありますか?

結論のビット この質問に答えてくれた皆さんに感謝します。いくつかの読み物と組み合わせると、次のように結論が得られます。

  1. values()は、最終的なsql( "のSELECT部分​​のルックアップフィールドに影響を与えます。values ()は、オプションの位置引数* fieldsを取ります。これは、SELECTを制限するフィールド名を指定します")
  2. order_by()は、そのパラメーターをSELECT部分​​にも追加します。
  3. ルックアップでdistinct()を使用すると、SQLは次のようになります。

    SELECT DISTINCT [fields1、fields2、fields3] FROM ... WHERE .. ..

    そして、フィールドの値がすべて一緒になって、レコードが一意であるかどうかを決定します。フィールドは、ルックアップのvalues()またはorder_by()関数から取得できます。

  4. したがって、order_by()は、distinct()と組み合わせると、いくつかの不要な効果を追加します。order_byで指定されたフィールドは、レコードが一意であるかどうかも考慮されます。

  5. Django Commentにはデフォルトで非表示のorder_byパラメーターがあるため、問題全体が発生します。qsを返すときに、どのモデルにもorder_byが隠されていると、同じ問題が発生する可能性があります。

  6. これを解決する方法は、ルックアップの最後に空のorder_by()を追加することです。これにより、デフォルトのorder_byが削除されます。
4

3 に答える 3

18
Comment.objects.values('user').distinct().order_by()
于 2012-01-26T12:20:11.930 に答える
6

これが原因であることを確認していませんが、モデルにはメソッドCommentに影響を与えるデフォルトの順序があります。distinct()

In [1]: print Comment.objects.values('ip_address').distinct().query
SELECT DISTINCT "django_comments"."ip_address", "django_comments"."submit_date" FROM "django_comments" ORDER BY "django_comments"."submit_date" ASC

これは文書化された機能です

では、2つのコメントのタイムスタンプがまったく同じであるとしたらどうでしょうか。1秒未満をサポートしないMySQLを使用していると思います。

また、デフォルトの順序を削除したい場合は、次のようにします。

Comment.objects.order_by().values('ip_address').distinct()
于 2012-01-26T13:05:11.677 に答える
1

クエリをセットでラップできます。

ドキュメントによると、distinct()はvalues()とうまく合いません

ip_sets = set(Comment.objects.order_by().values('ip_address'))
ip_list = list(set(Comment.objects.order_by().values('ip_address')))
于 2021-03-22T07:21:38.420 に答える