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をコーディングしたことはありませんが。
データベースから個別の列名のリストを取得する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"
_
ここで覚えておくべきことがいくつかあります。まず、これはValuesQuerySet
とは異なる動作をするQuerySet
を返します。 sayにアクセスすると、q
(上記)の最初の要素には、ProductOrder
のインスタンスではなく、dictionaryが返されます。
第二に、distinct()
の使用に関するドキュメントの warning note を読むことをお勧めします。上記の例は機能しますが、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()
_
実際には非常に簡単ですPostgreSQLを使用している場合、distinct(columns)
を使用してください。
Productorder.objects.all().distinct('category')
この機能はDjango= 1.4以降に含まれていることに注意してください。
他の答えは問題ありませんが、これは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 set
よりも速いと仮定します。
ユーザーはそのフィールドで並べ替えてから、個別に行います。
ProductOrder.objects.order_by('category').values_list('category', flat=True).distinct()