テーブルフィールドから個別の値を選択する


104

DjangoのORMに頭を悩ませています。私がしたいのは、テーブルのフィールド内の個別の値のリストを取得することです。次のいずれかに相当します。

SELECT DISTINCT myfieldname FROM mytable

(または代わりに)

SELECT myfieldname FROM mytable GROUP BY myfieldname

生のSQLに頼る前に、少なくともDjangoの方法でやりたいです。たとえば、テーブルの場合:

id、street、city

1、メインストリート、ハル

2、その他の通り、ハル

3、Bibble Way、レスター

4、別の方法、レスター

5、ハイストリート、ロンディジウム

入手したい:

ハル、レスター、ロンディジウム。

回答:


202

モデルが「ショップ」だとしましょう

class Shop(models.Model):
    street = models.CharField(max_length=150)
    city = models.CharField(max_length=150)

    # some of your models may have explicit ordering
    class Meta:
        ordering = ('city')

あなたが持っているかもしれないのでMeta、クラスのordering属性セットを、あなたは使用することができますorder_by()使用しているときの順序をクリアするには、パラメータなしdistinct()()のドキュメントを参照してくださいorder_by

クエリに順序付けを適用したくない場合、デフォルトの順序付けも含めない場合は、パラメーターなしでorder_by()を呼び出します。

またdistinct()distinct()注文での使用に関する問題について説明しているメモにも記載されています。

DBをクエリするには、次を呼び出すだけです。

models.Shop.objects.order_by().values('city').distinct()

辞書を返します

または

models.Shop.objects.order_by().values_list('city').distinct()

これValuesListQuerySetはにキャストできるa を返しますlist。を追加flat=Truevalues_listて結果を平坦化することもできます。

参照:クエリセットの個別の値をフィールドで取得する


29
実際に動作します。しかしながら!すべてのモデルで機能させることができませんでした。奇妙なことに、それはいくつかでは機能しましたが、他では機能しませんでした。メタ順序付けされているものについては機能しません。したがって、最初にクエリセットの順序をクリアする必要があります。models.Shop.objects.order_by()。values( 'city')。distinct()
alj

2
values_listは実際にはリストを返さないことに注意することが重要です。クエリセットのようなものを返します。values_list呼び出しの前後で常にlist()を使用すると便利です。
dheerosaur '19

8
values_listイテレータであるValuesListQuerySetを返します。リストへのキャストは便利な場合がありますが、すべての行を一度に評価する必要がある場合、特に大きなデータセットの場合はパフォーマンスが低下する可能性があります。
Peter Kilczuk、2012年

3
Meta: ordering = ()ジャンゴオームとobjects.distinct()vs の「機能」は、objects.ordering().distinct()何時間もの混乱を引き起こしました。その製品には消費者安全の警告ステッカーが貼られているはずです;)将来の誤操作を防ぐために、メタオーダー属性なしのポリシーを制定する場合があります。
ホブ

パラメータを指定せずに使用すると、Metaクラスorderingをオフにして問題を解決できます。これは、QuerySet APIドキュメントの「デフォルトの順序でさえも、クエリに順序を適用したくない場合は、パラメーターなしで呼び出します。distinctorder_by()order_by()order_by()
Mark Mikofski

11

まだ非常に関連することに加えてjujuleの答え、私はそれが非常に重要なもの意味を認識することを見つけるorder_by()distinct("field_name")クエリ。ただし、これはPostgresのみの機能です。

Postgresを使用していて、クエリを区別する必要があるフィールド名を定義する場合order_by()は、同じシーケンスで同じフィールド名(またはフィールド名)から始める必要があります(その後、フィールドが増える場合があります)。

注意

フィールド名を指定するときは、QuerySetにorder_by()を指定する必要があり、order_by()のフィールドは、distinct()のフィールドから同じ順序で開始する必要があります。

たとえば、SELECT DISTINCT ON(a)は、列aの各値の最初の行を提供します。順序を指定しないと、任意の行が表示されます。

eg-でお店を知っている都市のリストを抽出したい場合、jujuleの例をこれに適応させる必要があります。

# returns an iterable Queryset of cities.
models.Shop.objects.order_by('city').values_list('city', flat=True).distinct('city')  

2

例として:

# select distinct code from Platform where id in ( select platform__id from Build where product=p)
pl_ids = Build.objects.values('platform__id').filter(product=p)
platforms = Platform.objects.values_list('code', flat=True).filter(id__in=pl_ids).distinct('code')
platforms = list(platforms) if platforms else []
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.