コード例に出てくるProduct
、Order
、OrderDetail
はモデルクラス
検索系
全てのレコードを取得したい
products = Product.objects.all()
主キーを指定してレコードを取得したい
主キーのカラム名がなんであってもpk=
で検索できる
product = Product.objects.get(pk=1)
取得条件を指定してレコードを取得したい
products = Product.objects.filter(name="hoge")
取得条件を複数(AND)指定してレコードを取得したい
カンマ区切りで複数かくとANDになる
products = Product.objects.filter(name="hoge", size="L")
取得条件を複数(IN)指定してレコードを取得したい
<カラム名>=
の代わりに<カラム名>__in=
とする
products = Product.objects.filter(name__in=["hoge", "fuga"])
取得条件を複数(OR)指定してレコードを取得したい
Q(<条件>)
で一つの条件が生成できる。この式を|
で繋ぐとOR
になる。
from django.db.models import Q
products = Product.objects.filter(Q(name="hoge") | Q(name__startswith="foo"))
# -> name='hoge' OR name LIKE 'foo%'
大小比較の取得条件でレコードを取得したい
# weight > 2
products = Product.objects.filter(weight__gt=2)
# weight < 2
products = Product.objects.filter(weight__lt=2)
# weight >= 2
products = Product.objects.filter(weight__gte=2)
# weight <= 2
products = Product.objects.filter(weight__lte=2)
範囲条件でレコードを取得したい
# 4から12まで
# (weight BETWEEN 4 AND 12)
products = Product.objects.filter(weight__range=(4, 12))
SQLのIS NULL
(またはIS NOT NULL
)検索をしたい
# size IS NULL
products = Product.objects.filter(size__isnull=True)
# size IS NOT NULL
products = Product.objects.filter(size__isnull=False)
前方一致(LIKE)でレコードを取得したい
<カラム名>=
の代わりに<カラム名>__startswith=
とする
products = Product.objects.filter(name__startswith="ho")
中間一致(LIKE)でレコードを取得したい
<カラム名>=
の代わりに<カラム名>__contains=
とする
products = Product.objects.filter(name__contains="ho")
後方一致(LIKE)でレコードを取得したい
<カラム名>=
の代わりに<カラム名>__endswith=
とする
products = Product.objects.filter(name__endswith="ho")
昇順でソートして取得したい
name
の昇順
products = Product.objects.order_by("name")
filter()
がある場合はfilter()
の後に続けて書く
降順でソートして取得したい
name
の降順
products = Product.objects.order_by("-name")
filter()
がある場合はfilter()
の後に続けて書く
重複除去(SELECT DISTINCT)して取得したい
products = Product.objects.distinct("name", "created_on")
filter()
がある場合はfilter()
の後に続けて書く
辞書型として取得したい
products = Product.objects.values()
filter()
がある場合はfilter()
の後に続けて書く
特定のカラムの値のリストとして取得したい
sizes = Product.objects.values_list("size", flat=True)
# flat=Trueがないとタプルのリストになる
filter()
がある場合はfilter()
の後に続けて書く
結合(JOIN)して取得したい
select_related(<関連オブジェクト名>)
を使用する
orders = Order.objects.select_related("order_detail").all()
悲観ロックをしたい
select_for_update()
を使用する
products = Products.objects.select_for_update().filter(name__startswith="hoge")
with transaction.atomic():
# 通常はトランザクション内部でしかロックは意味を持たない
for product in products:
# productの更新処理など
ノンブロッキング処理を行いたい場合はnowait=True
を引数に追加する
レコードの件数を数えたい
product_count = Product.objects.count()
filter()
がある場合はfilter()
の後に続けて書く
合計を求めたい
from django.db.models import Sum
obj = Product.objects.aggregate(total_price=Sum("price"))
# -> obj = {"total_price": 24000}
filter()
がある場合はfilter()
の後に続けて書く
最新(最古)のレコードを取得したい
# 最新
latest_order = Order.objects.latest("created_on")
# 最古
earliest_order = Order.objects.earliest("created_on")
filter()
がある場合はfilter()
の後に続けて書く
最初(最後)のレコードを取得したい
# 最初
first_order = Order.objects.order_by("id").first()
# 最後
last_order = Order.objects.order_by("id").last()
filter()
がある場合はfilter()
の後に続けて書く
レコードの存在チェックをしたい
if
の条件に直接書く場合、
if Product.objects.filter(name="hoge").exists():
# name="hoge"のレコードがある場合、ここに入る
変数に代入する場合、
e = Product.objects.filter(name="hoge").exists()
# eにはTrueかFalseが入る
更新系
レコードを挿入したい
Product.objects.create(name="hoge", price=1200, size="M")
または、
product = Product(name="hoge", price=1200, size="M")
product.save()
レコードがあれば取得、なければ挿入したい
product, created = Product.objects.get_or_create(
name="hoge",
price=1200
defaults={size="S"}
)
- name="hoge"かつprice=1200のレコードがあれば取得して変数
product
に代入する。変数created
はFalseになる。 - name="hoge"かつprice=1200のレコードがなければname="hoge", price=1200, size="S"のレコードを作成し変数
product
に代入する。変数created
はTrueになる。
レコードがあれば更新、なければ挿入したい
product, created = Product.objects.update_or_create(
name="hoge",
price=1200
defaults={size="S"}
)
- name="hoge"かつprice=1200のレコードがあれば、size="S"に更新して変数
product
に代入する。変数created
はFalseになる。 - name="hoge"かつprice=1200のレコードがなければname="hoge", price=1200, size="S"のレコードを作成し変数
product
に代入する。変数created
はTrueになる。
特定のレコードの特定のカラムを更新したい
product = Product.objects.get(pk=1) # 条件を設定してから
product.name = "new onion" # 書き換えて
# ...書き換えるカラムは複数でも良い...
product.save() # 更新
条件にマッチするレコードを一括更新したい
products = Product.objects.filter(size="M") # 条件を設定してから
products.update(name="new onion") # 一括更新
条件にマッチするレコードを一括削除したい
products = Product.objects.filter(size="M") # 条件を設定してから
products.delete() # 一括削除