ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
Model とは
Django Model は DB テーブルに対応する Python クラスです。1 クラス = 1 テーブル、1 フィールド = 1 カラム、1 インスタンス = 1 レコード。
SQL を書かずに、Python のクラス定義でテーブル設計からクエリまでできるのが Django ORM の最大の特徴です。
最小の Model 定義
# myapp/models.py
from django.db import models
class User(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField(unique=True)
age = models.IntegerField(null=True, blank=True)
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = "users" # 任意。デフォルト app_user
ordering = ["-created_at"]
verbose_name = "ユーザー"
verbose_name_plural = "ユーザー一覧"
def __str__(self):
return self.name
フィールド型一覧
| フィールド | SQL 型 | 用途 |
|---|---|---|
CharField(max_length=N) | VARCHAR(N) | 短い文字列 |
TextField() | TEXT | 長文 |
IntegerField() | INTEGER | 整数 |
BigIntegerField() | BIGINT | 大きな整数 |
SmallIntegerField() | SMALLINT | 小さな整数 |
FloatField() | DOUBLE | 浮動小数 |
DecimalField(max_digits, decimal_places) | DECIMAL | 金額など正確な小数 |
BooleanField() | BOOLEAN | 真偽値 |
DateField() | DATE | 日付 |
DateTimeField() | DATETIME | 日時 |
TimeField() | TIME | 時刻 |
EmailField() | VARCHAR | メール (バリデーション付) |
URLField() | VARCHAR | URL |
SlugField() | VARCHAR | URL に使える短い識別子 |
FileField(upload_to=...) | VARCHAR (パス) | ファイルアップロード |
ImageField() | VARCHAR (パス) | 画像 (Pillow 必須) |
JSONField() | JSON | JSON データ |
UUIDField() | UUID | UUID 主キー |
共通オプション
| オプション | 意味 |
|---|---|
null=True | DB レベルで NULL を許可 |
blank=True | フォームで空を許可 |
default=値 | デフォルト値 |
unique=True | UNIQUE 制約 |
db_index=True | INDEX を作成 |
choices=[(...)] | 選択肢を制限 |
verbose_name="..." | 管理画面の表示名 |
help_text="..." | 説明文 |
editable=False | 管理画面で編集不可 |
リレーション
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=200)
# 1 対多: 1 著者が多数の本
author = models.ForeignKey(
Author,
on_delete=models.CASCADE, # 著者削除で本も削除
related_name="books", # author.books.all() でアクセス可
)
class Profile(models.Model):
# 1 対 1
user = models.OneToOneField(
"auth.User",
on_delete=models.CASCADE,
primary_key=True,
)
bio = models.TextField()
class Tag(models.Model):
name = models.CharField(max_length=30)
class Article(models.Model):
title = models.CharField(max_length=200)
# 多対多: 中間テーブル自動生成
tags = models.ManyToManyField(Tag, related_name="articles", blank=True)
on_delete の値
| 値 | 動作 |
|---|---|
CASCADE | 親削除で子も削除 |
PROTECT | 子があれば親削除を拒否 (例外) |
SET_NULL | 親削除で子の外部キーを NULL に (null=True 必須) |
SET_DEFAULT | 親削除で default 値に |
SET(値) | 特定値にセット |
DO_NOTHING | 何もしない (DB レベル制約に任せる) |
Meta クラス
class Article(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
published_at = models.DateTimeField()
class Meta:
db_table = "articles"
ordering = ["-published_at"]
verbose_name = "記事"
verbose_name_plural = "記事一覧"
unique_together = [["author", "slug"]] # 著者 × slug で一意
indexes = [
models.Index(fields=["published_at"]),
models.Index(fields=["author", "-published_at"]),
]
constraints = [
models.CheckConstraint(
check=models.Q(title__gt=""),
name="title_not_empty",
),
]
migrations の流れ
# 1. models.py を編集
# 2. マイグレーションファイル生成
python manage.py makemigrations
# → myapp/migrations/0001_initial.py が作られる
# 3. SQL を確認 (任意)
python manage.py sqlmigrate myapp 0001
# 4. DB に適用
python manage.py migrate
# 状態確認
python manage.py showmigrations
# マイグレーションを戻す
python manage.py migrate myapp 0001
python manage.py migrate myapp zero # 全部戻す
クエリ (ORM)
# 取得
User.objects.all()
User.objects.filter(is_active=True)
User.objects.filter(name__icontains="taro") # LIKE %taro% (case-insensitive)
User.objects.filter(age__gte=20, age__lt=30)
User.objects.exclude(is_active=False)
User.objects.get(pk=1) # 1 件、無ければ DoesNotExist
User.objects.first()
User.objects.count()
User.objects.exists()
# 並び替え・ページネーション
User.objects.order_by("-created_at")[:10]
# 作成
User.objects.create(name="taro", email="t@example.com")
u = User(name="hanako")
u.save()
# 更新
User.objects.filter(is_active=False).update(is_active=True)
u = User.objects.get(pk=1)
u.name = "改名"
u.save()
# 削除
User.objects.filter(is_active=False).delete()
# リレーション
book = Book.objects.select_related("author").get(pk=1)
author.books.all() # related_name 経由
article.tags.add(tag1, tag2)
article.tags.remove(tag1)
article.tags.set([tag1, tag3])
シグナル (signals)
モデルの保存・削除に処理をフックできます:
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
@receiver(post_save, sender=User)
def on_user_save(sender, instance, created, **kwargs):
if created:
print(f"新規ユーザー: {instance.name}")
@receiver(post_delete, sender=User)
def on_user_delete(sender, instance, **kwargs):
print(f"削除: {instance.name}")
FAQ
Q: マイグレーションがコンフリクト
A: python manage.py makemigrations --merge で統合マイグレーションを作成。
Q: null=True と blank=True の違い
A: null は DB レベル、blank はフォーム / バリデーションレベル。文字列系は null=True を避け blank=True のみ推奨 (空文字で扱う)。
Q: テーブル名を変えたい
A: class Meta: db_table = "custom_name" で指定。既存テーブルの rename は RenameModel マイグレーションが必要。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
同階層のページ
- ビュー(View)
- テンプレート(Template)
- モデル(Model)
- ルーティングの作成
- viewからtemplateへの遷移方法
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Laravel キャッシュクリア完全ガイド(cache:clear / config:clear / 2026-05-18 07:42:07
- プロジェクトの作成と削除 2026-05-18 07:42:07
- インストール直後にNetbeansが反応しない 2026-05-18 07:42:07
- 動画やチャンネルの検索 2026-05-18 07:42:07
- APIキー取得方法 2026-05-18 07:42:07
- チャンネル情報の取得 2026-05-18 07:42:07
- API 入門 — Web API(REST / GraphQL / gRPC / 2026-05-18 07:42:07
- インストール(eclipseプラグイン) 2026-05-18 07:42:07
- Laravel「Dotenv values containing spaces must be surrounded 2026-05-18 07:42:07
- エラー一覧 2026-05-18 07:42:07
- curl: (51) SSL: certificate subject name '~' does not match 2026-05-18 07:42:07
- インストール方法(Windows版) 2026-05-18 07:42:07
- JSONから配列に変換 2026-05-18 07:42:07
- 処理を一定時間待つ 2026-05-18 07:42:07
- A non well formed numeric value encountered 2026-05-18 07:42:07
コメントを削除してもよろしいでしょうか?