DjangoのORM(Object-Relational Mapping)の基本

プログラミング

Django ORM の基本

Django の Object-Relational Mapper (ORM) は、Python のオブジェクト指向プログラミングの概念を、データベースのテーブル構造にマッピングするための強力なツールです。これにより、開発者は SQL を直接記述することなく、Python コードでデータベース操作を行うことができます。この抽象化レイヤーにより、コードの可読性が向上し、データベースの種類に依存しないポータブルなコードを記述することが可能になります。

モデルの定義

Django ORM の中心となるのは「モデル」です。モデルは、データベースのテーブル構造を Python のクラスとして表現します。各クラスの属性は、テーブルの列に対応し、そのデータ型は Django のフィールドタイプによって定義されます。

モデルクラスの作成

モデルは `models.Model` を継承した Python クラスとして定義されます。

“`python
from django.db import models

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

def __str__(self):
return self.title
“`

この例では、`Article` というモデルを定義しています。`title` は最大 200 文字の文字列、`content` は長いテキスト、`publication_date` は自動的に現在の日時が設定される日時フィールドとして定義されています。`__str__` メソッドは、オブジェクトを人間が読める形式で表現するために使用されます。

フィールドタイプ

Django は、様々なデータ型に対応する豊富なフィールドタイプを提供しています。

  • CharField: 最大長を指定した短い文字列。
  • TextField: 長いテキスト。
  • IntegerField: 整数。
  • FloatField: 浮動小数点数。
  • BooleanField: 真偽値。
  • DateField: 日付。
  • DateTimeField: 日時。
  • ForeignKey: 他のモデルへのリレーションシップ(多対一)。
  • ManyToManyField: 他のモデルへのリレーションシップ(多対多)。
  • OneToOneField: 他のモデルへのリレーションシップ(一対一)。

データベースマイグレーション

モデルを定義したら、データベーススキーマを更新する必要があります。Django は「マイグレーション」という仕組みでこれを管理します。

マイグレーションの生成

モデルの変更を Django に認識させるために、以下のコマンドを実行します。

“`bash
python manage.py makemigrations
“`

これにより、モデルの変更を記述したマイグレーションファイルが `migrations` ディレクトリに生成されます。

マイグレーションの適用

生成されたマイグレーションをデータベースに適用するには、以下のコマンドを実行します。

“`bash
python manage.py migrate
“`

このコマンドは、データベースにテーブルを作成したり、既存のテーブルを変更したりします。

クエリセット

Django ORM のもう一つの重要な要素は「クエリセット」です。クエリセットは、データベースのレコードのコレクションを表し、フィルタリング、ソート、集計などの操作を行うためのメソッドを提供します。

オブジェクトの取得

クエリセットを使用して、データベースからオブジェクトを取得します。

  • Model.objects.all(): 全てのオブジェクトを取得します。
  • Model.objects.filter(**kwargs): 条件に一致するオブジェクトを取得します。
  • Model.objects.exclude(**kwargs): 条件に一致しないオブジェクトを取得します。
  • Model.objects.get(**kwargs): 条件に一致する単一のオブジェクトを取得します。一致しない場合や複数ある場合は例外が発生します。

“`python
# 全ての記事を取得
all_articles = Article.objects.all()

# タイトルが “Django ORM” の記事を取得
django_articles = Article.objects.filter(title=”Django ORM”)

# 公開日が特定の日付以降の記事を取得
from datetime import date
recent_articles = Article.objects.filter(publication_date__date__gt=date(2023, 1, 1))
“`

オブジェクトの作成、更新、削除

  • create(**kwargs): 新しいオブジェクトを作成し、データベースに保存します。
  • save(): オブジェクトをデータベースに保存します (新規作成または更新)。
  • delete(): オブジェクトをデータベースから削除します。

“`python
# 新しい記事を作成
new_article = Article.objects.create(title=”New Topic”, content=”This is a new article.”)

# 既存の記事を更新
article_to_update = Article.objects.get(title=”New Topic”)
article_to_update.content = “Updated content.”
article_to_update.save()

# 記事を削除
article_to_delete = Article.objects.get(title=”Article to be deleted”)
article_to_delete.delete()
“`

リレーションシップ

Django ORM は、モデル間のリレーションシップを簡単に定義できます。

ForeignKey

多対一のリレーションシップを定義します。例えば、`Comment` モデルが `Article` モデルに属する場合などです。

“`python
class Comment(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE)
text = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
“`

`on_delete=models.CASCADE` は、参照元のオブジェクトが削除された場合に、このオブジェクトも削除されることを意味します。

ManyToManyField

多対多のリレーションシップを定義します。例えば、`Article` モデルが複数の `Tag` モデルを持つ場合などです。

“`python
class Tag(models.Model):
name = models.CharField(max_length=50)

class Article(models.Model):
# … (前の定義)
tags = models.ManyToManyField(Tag)
“`

リレーションシップを使用したクエリ

リレーションシップを通じて、関連するオブジェクトにアクセスできます。

“`python
# 特定の記事に紐づくコメントを取得
comments_for_article = Comment.objects.filter(article__title=”Django ORM”)

# 特定の記事に紐づくタグを取得
article_with_tags = Article.objects.prefetch_related(‘tags’).get(title=”Example Article”)
for tag in article_with_tags.tags.all():
print(tag.name)
“`

高度な機能

Django ORM は、さらに多くの高度な機能を提供しています。

  • QuerySet の遅延評価: クエリセットは、実際にデータが必要になるまでデータベースクエリを実行しません。
  • QuerySet のキャッシュ: 一度評価されたクエリセットはキャッシュされ、再度アクセスする際にデータベースクエリが実行されません。
  • Annotation と Aggregation: クエリセットにカスタムフィールドを追加したり、集計値 (合計、平均など) を取得したりできます。
  • Raw SQL クエリ: 必要に応じて、生の SQL クエリを実行することも可能です。

まとめ

Django ORM は、Python のオブジェクト指向の概念をデータベース操作に統合することで、開発プロセスを大幅に効率化します。モデル定義、マイグレーション、クエリセット、リレーションシップの管理を直感的に行えるため、開発者はビジネスロジックに集中できます。SQL の知識がなくてもデータベースを操作でき、データベースの種類に依存しないコードを書けることは、Django ORM の大きな利点です。その柔軟性と強力な機能により、小規模なプロジェクトから大規模なアプリケーションまで、幅広い開発ニーズに対応できます。