142

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、ハイストリート、ロンディニウム

取得したい:

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

4

4 に答える 4

268

モデルが「ショップ」であるとしましょう

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これは、にキャストできるを返しますlistflat=Trueに追加しvalues_listて、結果をフラット化することもできます。

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

于 2010-03-18T09:23:19.740 に答える
21

まだ非常に関連性の高いjujuleの回答に加えて、クエリへの影響order_by()を認識することも非常に重要だと思います。ただし、これはPostgresのみの機能です。distinct("field_name")

Postgresを使用していて、クエリを区別する必要のあるフィールド名を定義する場合はorder_by()、同じ順序で同じフィールド名(または複数のフィールド名)で開始する必要があります(後でさらにフィールドが存在する場合があります)。

ノート

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

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

たとえば、お店を知っている都市のリストを抽出する場合は、jujuleの例を次のように適合させる必要があります。

# returns an iterable Queryset of cities.
models.Shop.objects.order_by('city').values_list('city', flat=True).distinct('city')  
于 2018-05-24T07:31:10.780 に答える
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 []
于 2018-08-06T01:33:57.140 に答える
0

PostgreSQLを使用せず、使用できる特定のフィールドを1つだけ取得して区別したい場合

MyModel.objects.values('name').annotate(Count('id')).order_by()

このクエリセットは、「name」フィールドが同じ名前の行の数で一意である行を返します

<QuerySet [{'name': 'a', 'id__count': 2}, {'name': 'b', 'id__count': 2}, {'name': 'c', 'id__count': 3}>

返されたデータが完全ではなく、満足できない場合もありますが、役立つ場合もあります。

ドキュメントリファレンス

于 2022-01-05T20:43:48.640 に答える