120

Django で " " 以外のクエリを実行する方法があるかどうか知りたいですSELECT * FROM...SELECT DISTINCT columnName FROM ...代わりに" " を実行しようとしています。

具体的には、次のようなモデルがあります。

class ProductOrder(models.Model):
   Product  = models.CharField(max_length=20, promary_key=True)
   Category = models.CharField(max_length=30)
   Rank = models.IntegerField()

ここで、Rankは 内のランクCategoryです。そのカテゴリ内の各ランクで何らかの操作を行って、すべてのカテゴリを反復処理できるようにしたいと考えています。

最初にシステム内のすべてのカテゴリのリストを取得し、次にそのカテゴリ内のすべての製品を照会して、すべてのカテゴリが処理されるまで繰り返したいと思います。

私はむしろ生の SQL を避けたいと思っていますが、そこに行く必要がある場合は、それで問題ありません。Django/Python で生の SQL をコーディングしたことはありませんが。

4

4 に答える 4

219

データベースから個別の列名のリストを取得する 1 つの方法はdistinct() 、 と組み合わせて使用​​することvalues()です。

あなたの場合、次のようにして、個別のカテゴリの名前を取得できます。

q = ProductOrder.objects.values('Category').distinct()
print q.query # See for yourself.

# The query would look something like
# SELECT DISTINCT "app_productorder"."category" FROM "app_productorder"

ここで覚えておくべきことがいくつかあります。まず、これは aValuesQuerySetとは異なる動作をする a を返しQuerySetます。qたとえば、 (上記の)の最初の要素にアクセスすると、のインスタンスではなく、辞書ProductOrderが取得されます。

第二に、の使用に関するドキュメントの警告メモを読むことをお勧めしますdistinct()。上記の例は機能しますが、 と のすべての組み合わせは機能distinct()values()ない場合があります。

PS :モデル内のフィールドには小文字の名前を使用することをお勧めします。あなたの場合、これは以下に示すようにモデルを書き直すことを意味します:

class ProductOrder(models.Model):
    product  = models.CharField(max_length=20, primary_key=True)
    category = models.CharField(max_length=30)
    rank = models.IntegerField()
于 2010-10-04T05:30:09.720 に答える
84

PostgreSQL を使用している場合、実際には非常に簡単です。 distinct(columns)( documentation )を使用するだけです。

Productorder.objects.all().distinct('category')

この機能は Django 1.4 以降に含まれていることに注意してください。

于 2010-10-04T00:22:09.897 に答える
19

ユーザーはそのフィールドで並べ替えてから、区別します。

ProductOrder.objects.order_by('category').values_list('category', flat=True).distinct()
于 2015-10-15T08:31:43.460 に答える
18

他の答えは問題ありませんが、Django からのクラフトなしで、DISTINCT クエリから取得するような値のみを提供するという点で、これは少しクリーンです。

>>> set(ProductOrder.objects.values_list('category', flat=True))
{u'category1', u'category2', u'category3', u'category4'}

また

>>> list(set(ProductOrder.objects.values_list('category', flat=True)))
[u'category1', u'category2', u'category3', u'category4']

また、PostgreSQL がなくても動作します。

これは、データベース内の DISTINCT が python よりも高速であると仮定すると、.distinct() を使用するよりも効率的ではありませんがset、シェルの周りをうろつくには最適です。

更新:これは、開発中に Django シェルでクエリを作成するのに最適な回答です。を適用する前に常にごく少数の結果が得られることが確実でない限り、このソリューションを本番環境で使用しないでくださいset。そうでなければ、パフォーマンスの観点からはひどい考えです。

于 2015-02-02T23:00:23.523 に答える