モデルの使い方がいまいち覚えられないので、ちょっとまとめてみることにした。Djangoのドキュメントってちょっと分かりにくいよねぇ。Pythonのドキュメントも分かりにくいけど。チュートリアルなのか、リファレンスなのか、ごちゃごちゃになっているからかもしれない。使い方2では内部結合・外部結合について書くつもりだけど、納得できるまで書かないので、書けない可能性もある。エンティティどうしが結合する場合、Entity Frameworkみたいに新しいエンティティを作らないといけないのだろうか。それとも合成せずに簡単にかけるのか。

単純なSELECT文

まずは、簡単なSELECT文の使い方をまとめておく。ホントはGROUP BYとかもあったんだけど、annotateの使い方も良く分かってないので、これも後日書く予定。

以下の例は基本的にQuerySetが返ってくる。一部辞書のリストとか、タプルのリストが返ってくるものもある。オブジェクトを取得したい場合はfilterじゃなくて、getを使うこと。getは1レコードだけを取得する場合のみ使用可能なので、注意が必要。

全件取得

#SELECT * FROM Entry
Entry.objects.all()

カラム指定(辞書のリストを返す)

#SELECT id, pubdate FROM Entry
Entry.objects.values('id', 'pub_date')
# Blog オブジェクトのリストを返します。
>>> Blog.objects.filter(name__startswith='Beatles')
[<Blog: Beatles Blog>]
# 辞書のリストを返します。
>>> Blog.objects.filter(name__startswith='Beatles').values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]

カラム指定(タプルのリストを返す)

Entry.objects.values_list('id', 'pub_date')
>>> Entry.objects.values_list('id').order_by('id')
[(1,), (2,), (3,), ...]
>>> Entry.objects.values_list('id', flat=True).order_by('id')
[1, 2, 3, ...]

検索条件

#SELECT * FROM Entry WHERE pub_date > '2005-1-3'
Entry.objects.filter(pub_date__gt=datetime.date(2005, 1, 3))

除外条件

#SELECT * FROM Entry WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello')
Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')
#SELECT * FROM Entry WHERE NOT pub_date > '2005-1-3' AND NOT headline = 'Hello'
Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello')

ソート

#SELECT * FROM Entry ORDER BY pub_date DESC, headline ASC
Entry.objects.order_by('-pub_date', 'headline')
#SELECT * FROM Entry ORDER BY blog.name ASC, headline ASC
Entry.objects.order_by('blog__name', 'headline')
#SELECT * FROM Entry(整列解除)
Entry.objects.order_by()

ランダムソート

Entry.objects.order_by('?')

Distinct

#SELECT DISTINCT * FROM Etnry
Entry.objects.distinct()

上位n件

#SELECT * FROM Entry LIMIT n
Entry.objects.all()[:n]

上位n件(offset a)

#SELECT * FROM Entry LIMIT a,n
Entry.objects.all()[a:n]

件数

#SELECT COUNT(*) FROM Entry
Entry.objects.count()

Null

評価結果が常に空のリストであるクエリセットであるEmptyQuerySetを返す。

#SELECT NULL
Entry.objects.none()

参考

Django v1.0 documentation