ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
Django モデルとテーブルの関係
Django ORM では models.py に書いた Python クラスが、そのまま 1 つの DB テーブルに対応します。フィールド型は SQL の DDL に自動変換され、マイグレーション機能で世代管理されます。スキーマ変更も全部 Python コードで管理できるのが強み。
| Python クラス | ↔ | DB テーブル |
|---|---|---|
| class Post(models.Model) | ↔ | blog_post テーブル |
| title = CharField(max_length=200) | ↔ | title VARCHAR(200) |
| created_at = DateTimeField() | ↔ | created_at DATETIME |
| author = ForeignKey(User) | ↔ | author_id BIGINT + FK 制約 |
基本のモデル定義
# blog/models.py
from django.db import models
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField('カテゴリ名', max_length=50, unique=True)
slug = models.SlugField(max_length=50, unique=True)
class Meta:
db_table = 'blog_category'
verbose_name = 'カテゴリ'
verbose_name_plural = 'カテゴリ一覧'
ordering = ['name']
def __str__(self):
return self.name
class Post(models.Model):
STATUS_CHOICES = [
('draft', '下書き'),
('published', '公開'),
('archived', 'アーカイブ'),
]
title = models.CharField('タイトル', max_length=200)
body = models.TextField('本文')
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='draft')
view_count = models.PositiveIntegerField(default=0)
author = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='posts',
verbose_name='著者',
)
category = models.ForeignKey(
Category,
on_delete=models.SET_NULL,
null=True, blank=True,
related_name='posts',
)
tags = models.ManyToManyField('Tag', blank=True, related_name='posts')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
published_at = models.DateTimeField(null=True, blank=True)
class Meta:
db_table = 'blog_post'
ordering = ['-created_at']
indexes = [
models.Index(fields=['status', '-created_at']),
models.Index(fields=['author', 'status']),
]
constraints = [
models.UniqueConstraint(
fields=['author', 'title'],
name='unique_author_title',
),
]
def __str__(self):
return self.title
class Tag(models.Model):
name = models.CharField(max_length=30, unique=True)
def __str__(self):
return self.name
主なフィールド型
| Django フィールド | 用途 | SQL 型 (PostgreSQL 例) |
|---|---|---|
CharField(max_length=N) | 短い文字列(必須: max_length) | VARCHAR(N) |
TextField() | 長文 | TEXT |
SlugField(max_length=50) | URL 用識別子 | VARCHAR(50) |
EmailField() | メールアドレス(バリデーション付き) | VARCHAR(254) |
URLField() | URL | VARCHAR(200) |
IntegerField() | 整数 | INTEGER |
BigIntegerField() | 大きな整数 | BIGINT |
PositiveIntegerField() | 0 以上の整数 | INTEGER CHECK (>= 0) |
FloatField() | 浮動小数点 | DOUBLE PRECISION |
DecimalField(max_digits, decimal_places) | 金額・正確な小数 | NUMERIC |
BooleanField() | 真偽値 | BOOLEAN |
DateField() | 日付 | DATE |
DateTimeField() | 日時 | TIMESTAMP |
TimeField() | 時刻 | TIME |
JSONField() | JSON(Django 3.1+) | JSONB (PostgreSQL) |
FileField(upload_to=...) | ファイルアップロード | VARCHAR (パス) |
ImageField(upload_to=...) | 画像(Pillow 必須) | VARCHAR (パス) |
UUIDField(default=uuid.uuid4) | UUID 主キー | UUID |
リレーション 3 種
| 種類 | フィールド | 例 |
|---|---|---|
| 多対 1 | ForeignKey | 記事 N - 著者 1 |
| 1 対 1 | OneToOneField | User - Profile |
| 多対多 | ManyToManyField | 記事 N - タグ N |
on_delete の選択肢
# author が削除されたときの挙動
author = models.ForeignKey(User, on_delete=models.CASCADE)
# CASCADE - 関連も一緒に削除
# PROTECT - 関連があれば削除をエラーに
# SET_NULL - NULL にする (null=True 必須)
# SET_DEFAULT - デフォルト値にする (default 必須)
# SET(関数) - 任意の関数で値設定
# DO_NOTHING - 何もしない (SQL レベルの FK 制約による)
多対多の through テーブル
# 追加情報(タグ付与日など)を中間テーブルに持たせたい場合
class Post(models.Model):
tags = models.ManyToManyField('Tag', through='PostTag')
class PostTag(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
tag = models.ForeignKey('Tag', on_delete=models.CASCADE)
added_at = models.DateTimeField(auto_now_add=True)
weight = models.IntegerField(default=1)
class Meta:
unique_together = ('post', 'tag')
マイグレーションの実行
# 1. マイグレーションファイル生成
python manage.py makemigrations blog
# blog/migrations/0001_initial.py が生成される
# 2. 生成された SQL を確認(実行はしない)
python manage.py sqlmigrate blog 0001
# 3. DB に反映
python manage.py migrate
# 4. 適用状態の確認
python manage.py showmigrations
# 5. ロールバック(前の世代に戻す)
python manage.py migrate blog 0001
# 6. ゼロまで戻す
python manage.py migrate blog zero
admin.py に登録
# blog/admin.py
from django.contrib import admin
from .models import Post, Category, Tag, PostTag
class PostTagInline(admin.TabularInline):
model = PostTag
extra = 1
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ('id', 'title', 'author', 'category', 'status', 'created_at')
list_filter = ('status', 'category', 'created_at')
search_fields = ('title', 'body')
raw_id_fields = ('author',)
inlines = [PostTagInline]
date_hierarchy = 'created_at'
admin.site.register(Category)
admin.site.register(Tag)
主キー(id)の挙動
明示しなければ id BIGAUTO が自動で追加されます(Django 3.2+)。UUID 主キーにしたいときは:
import uuid
class Post(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=200)
FAQ
Q: 既存 DB に Django を載せたい(マイグレーション不要)
A: python manage.py inspectdb > models.py で既存テーブルから models を逆生成。各モデルで class Meta: managed = False を付けると Django が DDL に介入しなくなります。
Q: マイグレーションファイルをやり直したい
A: 開発初期なら migrations/ 内の 0001_initial.py 以降を削除 + DB をリセット + 再 makemigrations。本番では絶対やらない。
Q: フィールド追加で「default を聞かれる」
A: 既存レコードに対する初期値が必要。default= を付ける、null=True を付ける、または対話プロンプトで一時値を指定します。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページ
子ページはありません
同階層のページ
人気ページ
- 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アノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?