DjangoのQオブジェクトの使い方: OR検索、否定
目次
DjangoのQオブジェクトの使い方
Djangoではfilter()
でDBのレコードを検索することができます。
その時にOR検索や否定条件を指定したい時があります。
そういう時はQオブジェクトを使うと簡単にできます。
この記事ではDjangoのQオブジェクトについて具体的に解説します。
具体的には↓の項目を見ていきます。
Qオブジェクトのインポート方法
普通に検索
OR検索
AND検索
否定
関連記事
前提とするプロジェクト構造
今回の解説に使用するプロジェクトは↓のようなモデルを持ちます。
from django.db import models class Article(models.Model): title = models.CharField(max_length=255, help_text='記事のタイトル') content = models.TextField(max_length=4096, help_text='記事の内容')
Article
という記事を表現するモデルを定義しています。
Article
はtitle
とcontent
というフィールドを持ちます。
title
には記事のタイトル、content
には記事の内容が保存されます。
それからDBは↓のスクリプトで初期化している前提です。
from myapp.models import Article for a in Article.objects.all(): a.delete() Article.objects.create(title='鳥になりたい', content='') Article.objects.create(title='猫の額ほど狭い', content='') Article.objects.create(title='犬になりたい', content='') Article.objects.create(title='犬も歩けば棒に当たる', content='')
$ python manage.py shell < init.py
検証するDBには合わせて4レコードが挿入されています。
それぞれ鳥や猫、犬などのワードをtitleに含みます。
Qオブジェクトのインポート方法
Qオブジェクトをインポートするには↓のコードを書きます。
from django.db.models import Q
Qオブジェクト自体はquery_utils.py
というモジュールに定義されています。
QオブジェクトはNode
を継承したオブジェクトで、Node
の持つメソッド(add
)も合わせて使うことができます。
普通に検索
QオブジェクトをORもANDも行わずに普通に使う方法です。
↓のようにQオブジェクトをフィルターに渡します。
# 普通に使う articles = Article.objects.filter(Q(title__icontains='鳥')).all() print([a.title for a in articles]) # ['鳥になりたい']
Qオブジェクトの引数にはfilter()
の検索条件と同様のパラメーターを指定します。
↑の場合はtitle__icontains
を指定しています。
これはArticle
のtitle
に「鳥」が含まれているか? という条件になります。
Qオブジェクトを渡したfilter()
はQオブジェクトの条件でDBを検索します。
↑の場合だと「鳥になりたい」というtitle
を持つレコードがヒットしています。
OR検索
QオブジェクトでOR検索する方法です。
Qオブジェクトを「|
」で繋げるとOR検索になります。
あるいはadd()
に「Q.OR
」を渡しても同様です。
# OR検索 articles = Article.objects.filter( Q(title__icontains='鳥') | Q(title__icontains='猫') ).all() print([a.title for a in articles]) # ['鳥になりたい', '猫の額ほど狭い'] # OR検索 その2 q = Q() q.add(Q(title__icontains='鳥'), Q.OR) q.add(Q(title__icontains='猫'), Q.OR) articles = Article.objects.filter(q).all() print([a.title for a in articles]) # ['鳥になりたい', '猫の額ほど狭い']
↑の前者のOR検索では「Q(title__icontains='鳥') | Q(title__icontains='猫')
」という条件を指定しています。
これは「title
に鳥、または猫が含まれる」という条件指定になります。
この条件だとArticle
のtitle
に鳥、または猫が含まれるレコードがヒットします。
またQオブジェクトをインスタンス化してq
にして、このq
のメソッドadd()を呼び出すことでも条件を追加できます(↑の後者のAND検索)。
add()
の第1引数にはQオブジェクトで条件を指定します。
そして第2引数には演算子を指定します。
↑の場合だとQ.OR
を指定しているので条件はOR検索用になります。
AND検索
QオブジェクトでAND検索する方法です。
Qオブジェクトを「&
」で繋げるとAND検索になります。
# AND検索 articles = Article.objects.filter( Q(title__icontains='犬') & Q(title__icontains='棒') ).all() print([a.title for a in articles]) # ['犬も歩けば棒に当たる'] # AND検索 その2 q = Q() q.add(Q(title__icontains='犬'), Q.AND) q.add(Q(title__icontains='棒'), Q.AND) articles = Article.objects.filter(q).all() print([a.title for a in articles]) # ['犬も歩けば棒に当たる']
↑の前者のAND検索では「犬」と「棒」でAND検索しています。
この条件だとArticle
のtitle
に犬と棒が含まれるレコードがヒットします。
またAND検索もQオブジェクトのadd()で指定することができます。
↑の後者のAND検索ではQオブジェクトをインスタンス化して、add()
メソッドを呼び出しています。
add()
の第1引数にはQオブジェクトで条件を指定し、第2引数にはQ.AND
を指定します。
こうすることでadd()
で追加していく条件がAND
で結合されます。
否定
Qオブジェクトを使うと否定条件も書くことが出来ます。
否定にはQオブジェクトに「~
」を指定します。
# 否定 articles = Article.objects.filter(~Q(title__icontains='犬')).all() print([a.title for a in articles]) # ['鳥になりたい', '猫の額ほど狭い']
↑の場合だと「~Q(title__icontains='犬')
」という条件を指定しています。
この条件だと「title
に犬を含まない記事」にレコードがヒットします。
また、この否定演算子はORやANDとも合わせて使うことが可能です。
おわりに
今回はDjangoのQオブジェクトについて解説しました。
Qオブジェクトは複雑な条件を指定して検索したい時に役立つオブジェクトです。
Djangoではわりと頻繁に使われます。
Qオブジェクトの使い方をマスターしておけばきっと役に立つでしょう。
(^ _ ^) | QあんどD |
(・ v ・) | QあんどDjangoね |