🦅

Django 逆引き(QuerySet)

2021/10/19に公開約3,700字

これらを理解しておくと、データベースから効率よく取得できます。

検索

全てのレコードを取得

posts = Post.objects.all()

主キーを指定してレコードを取得

post = Post.objects.get(pk=1)

URL 内の変数を指定してレコードを取得

posts = Post.objects.get(id=self.kwargs['pk'])
posts = Post.objects.get(name=self.kwargs['category'])

条件を指定してレコードを取得

posts = Post.objects.filter(name="test")

条件を指定してレコードを取得(AND)

posts = Post.objects.filter(name="test", author="django")

条件を指定してレコードを取得(リスト)

posts = Post.objects.filter(name__in=["test", "test2"])
# QuerySetでフィルターすることも可能
comments = Comment.objects.all()
posts = Post.objects.filter(comment__in=comments)

条件を指定してレコードを取得(OR)

from django.db.models import Q
posts = Post.objects.filter(Q(name="test") | Q(name="test2"))

大小比較の取得条件でレコードを取得

# test > 10
posts = Post.objects.filter(size__gt=10)
# test < 10
posts = Post.objects.filter(size__lt=10)
# test >= 10
posts = Post.objects.filter(size__gte=10)
# test <= 10
posts = Post.objects.filter(size__lte=10)

範囲を指定してレコードを取得

# 1から10まで
posts = Post.objects.filter(size__range=(1, 10))

NULL のレコードを取得

posts = Post.objects.filter(size__isnull=True)

完全一致(大文字小文字区別有り)でレコードを取得

posts = Post.objects.filter(name__exact="test")

完全一致(大文字小文字区別無し)でレコードを取得

posts = Post.objects.filter(name__iexact="TeSt")

前方一致(大文字小文字区別有り)でレコードを取得

posts = Post.objects.filter(name__startswith="django")

前方一致(大文字小文字区別無し)でレコードを取得

posts = Post.objects.filter(name__istartswith="Django")

中間一致(大文字小文字区別有り)でレコードを取得

posts = Post.objects.filter(name__contains="start")

中間一致(大文字小文字区別無し)でレコードを取得

posts = Post.objects.filter(name__icontains="Start")

後方一致(大文字小文字区別有り)でレコードを取得

posts = Post.objects.filter(name__endswith="up")

後方一致(大文字小文字区別無し)でレコードを取得

posts = Post.objects.filter(name__iendswith="up")

検索してレコードを取得

posts = Post.objects.filter(name__search="test")

昇順でソートして取得

posts = Post.objects.order_by("id")
posts = Post.objects.filter(name="test").order_by("id")

降順でソートして取得

posts = Post.objects.order_by("-id")
posts = Post.objects.filter(name="test").order_by("-id")

辞書型として取得

posts = Post.objects.values()
posts = Post.objects.filter(name="test").values()

特定のカラムの値のリストとして取得

posts = Post.objects.values_list("name", flat=True)

結合して取得

# select_related(<関連オブジェクト名>)
posts = Post.objects.select_related("detail").all()

レコードの件数

count = Post.objects.count()
count = Post.objects.filter(name="test").count()

合計を取得

from django.db.models import Sum
total = Post.objects.aggregate(total=Sum("size"))
# total = {"total": 1000}

最新のレコードを取得

post = Post.objects.latest("created_on")

最古のレコードを取得

post = Post.objects.earliest("created_on")

最初のレコードを取得

post = Post.objects.order_by("id").first()

最後のレコードを取得

post = Post.objects.order_by("id").last()

レコードの存在を確認

is_post = Post.objects.filter(name="test").exists()

更新

レコードを挿入

post = Post(name="test", size=100))
post.save()

レコードがあれば取得、なければ挿入

post, created = Post.objects.get_or_create(
  name="test",
  size=100
  defaults={test="django"}
)

レコードがあれば更新、なければ挿入

post, created = Post.objects.update_or_create(
  name="test",
  size=100
  defaults={test="django"}
)

特定のレコードの特定のカラムを更新

post = Post.objects.get(pk=1)
post.name = "django"
post.save()

条件にマッチするレコードを一括更新

posts = Post.objects.filter(name="django")
posts.update(size=10)

条件にマッチするレコードを一括削除

posts = Post.objects.filter(name="django")
posts.delete()

Discussion

ログインするとコメントできます