【Django入門12】Django ORMと基本クエリ|データベース操作の基礎をマスターしよう

Django ORMとは?

ORMの基本概念

ORM(Object-Relational Mapping)は、オブジェクト指向のプログラミング言語でデータベース操作を簡単に行うための仕組みです。DjangoのORMを使えば、複雑なSQL文を書かなくてもPythonコードだけでデータベースの操作が可能です。

Django ORMの特徴

  • シンプルなコードでデータ操作が可能:Pythonのメソッド呼び出しでデータベース操作が行えます。
  • データベースに依存しない設計:SQLite、PostgreSQL、MySQLなど、さまざまなデータベースを簡単に切り替えられます。
  • セキュリティの向上:SQLインジェクションの脅威から保護されます。

モデルの定義とマイグレーション

モデルの基本構造

Djangoでは、データベースのテーブルに対応するモデルをPythonクラスとして定義します。各フィールドはデータベースのカラムに対応します。

例:BlogPostモデルの定義

from django.db import models

class BlogPost(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    published_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

マイグレーションの適用

  1. マイグレーションファイルの作成 python manage.py makemigrations
  2. マイグレーションの適用 python manage.py migrate

これにより、データベースに対応するテーブルが作成されます。

基本的なクエリ操作

データの作成(INSERT)

Djangoではcreate()メソッドやsave()メソッドを使って新しいレコードを追加できます。

例:オブジェクトの作成と保存

# オブジェクトの直接保存
post = BlogPost(title="初めての投稿", content="Django ORMを学習中です。")
post.save()

# create()メソッドを使用
BlogPost.objects.create(title="2つ目の投稿", content="さらに学習を進めています。")

データの取得(SELECT)

  • 全レコードを取得all()メソッドを使用します。
  • フィルタリングして取得filter()メソッドを使用して条件を指定します。
  • 単一レコードの取得get()メソッドを使用します。

例:基本的なデータ取得

# すべての投稿を取得
posts = BlogPost.objects.all()

# 特定の条件で投稿をフィルタリング
filtered_posts = BlogPost.objects.filter(title__icontains="投稿")

# 単一の投稿を取得
single_post = BlogPost.objects.get(id=1)
  • title__icontains:部分一致検索(大文字小文字を区別しない)。
  • get():条件に合致するレコードが1件であることが保証されている場合に使用します。複数のレコードが見つかるとエラーになります。

データの更新(UPDATE)

取得したオブジェクトを変更し、save()メソッドを呼び出すことでデータを更新できます。

例:データの更新

post = BlogPost.objects.get(id=1)
post.title = "更新されたタイトル"
post.save()

データの削除(DELETE)

取得したオブジェクトに対してdelete()メソッドを呼び出すと、データベースからレコードが削除されます。

例:データの削除

post = BlogPost.objects.get(id=1)
post.delete()

フィルタリングとクエリの条件指定

フィールドルックアップ

Django ORMでは、さまざまな条件指定を行うための「フィールドルックアップ」が用意されています。

ルックアップ説明
exact完全一致filter(title__exact="タイトル")
icontains部分一致(大文字小文字を無視)filter(content__icontains="Django")
gte, lte範囲条件(以上、以下)filter(published_at__gte="2023-01-01")
isnullNULLチェックfilter(content__isnull=True)

例:フィールドルックアップの使用

# タイトルが「特別な投稿」と完全一致する投稿を取得
exact_match = BlogPost.objects.filter(title__exact="特別な投稿")

# 日付が2023年以降の投稿を取得
recent_posts = BlogPost.objects.filter(published_at__gte="2023-01-01")

Qオブジェクトを使った複雑なクエリ

複数の条件を組み合わせたい場合、Qオブジェクトを使用すると便利です。

例:複数条件の組み合わせ

from django.db.models import Q

# タイトルに「Django」を含むか、または内容に「学習」を含む投稿を取得
posts = BlogPost.objects.filter(Q(title__icontains="Django") | Q(content__icontains="学習"))
  • |:OR条件。
  • &:AND条件。

集計クエリとアノテーション

集計関数

DjangoのORMでは、aggregate()メソッドを使ってデータの集計を行えます。

例:投稿数のカウント

from django.db.models import Count

post_count = BlogPost.objects.aggregate(Count('id'))
print(post_count)  # {'id__count': 投稿数}

アノテーション

annotate()メソッドを使って各レコードに集計結果を付加することも可能です。

例:各著者ごとの投稿数を表示

from django.db.models import Count

authors_with_post_counts = BlogPost.objects.values('author').annotate(post_count=Count('id'))

まとめ

Django ORMを使えば、SQLを直接書かずに直感的なPythonコードでデータベースを操作できます。基本的なCRUD操作(作成、取得、更新、削除)や条件付きクエリ、さらには集計まで幅広い操作が可能です。初心者はまず基本的なクエリから始め、徐々に複雑なクエリへステップアップしていくと良いでしょう。