こんにちは!前回の記事では、主にアプリの要件定義を書いてみました。
これまでは Django 本体のみで開発しており、Django関連のライブラリは使ったことがありませんでした。
より効率的な開発を目指して
Django REST Framework (DRF) を導入し、まずはシリアライザーから使ってみることにしました!
views.pyの記述をだいぶ簡潔にすることができます。
バリデーション処理やデータ変換処理を簡潔に行えるので参考になれば幸いです。
🔍 調べたこと
参考にさせていただいた記事はこちらです👇
シリアライザーを使う目的とは?
シリアライザーは Django REST Framework の中核機能で、主に次の2つの役割を担っています👇
① データの変換
データベースのモデルオブジェクトをJSON形式に変換し、APIレスポンスとして返す
クライアントから送信されたJSONデータをモデルオブジェクトに変換し、データベースに保存する
② データのバリデーション
-
入力されたデータの形式や必須項目のチェックを自動で行ってくれる
-
例えば文字数や空欄チェック、ユニーク制約などもここで確認できます!
📝 まとめると →
views.py内で手書きしていたバリデーション処理やデータ変換処理を、シリアライザに任せられるので、
コードがスッキリしてメンテナンスしやすくなります!
🧰 ライブラリ準備
まず、django-extensions
をインストールして、settings.py
に追加しました。
INSTALLED_APPS = [
...
'django_extensions', # Django Extensions を追加
'ingredients', # 食材アプリ
'recipes', # レシピアプリ
]
🏗 実際のモデル(models.py)
📁 recipes/models.py(レシピ提案アプリ)
from django.db import models
from ingredients.models import Ingredient
class Category(models.Model):
name = models.CharField(max_length=50) # カテゴリ名
def __str__(self):
return self.name
class Recipe(models.Model):
name = models.CharField(max_length=100, unique=True, help_text="レシピ名を入力してください")
url = models.URLField(unique=True, help_text="YouTubeのURLを入力してください")
thumbnail = models.URLField(help_text="サムネイル画像のURLを入力してください")
notes = models.TextField(blank=True, null=True, help_text="備考を入力してください")
ingredients = models.ManyToManyField(Ingredient, related_name='recipes', help_text="使用する食材を選択してください")
categories = models.ManyToManyField(Category, related_name='recipes', help_text="カテゴリを選択してください")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
📁 ingredients/models.py(食材登録アプリ)
from django.db import models
class Ingredient(models.Model):
TYPE_CHOICES = [
('肉・魚・大豆・卵', '肉・魚・大豆・卵'),
('野菜', '野菜'),
('米・麺・パスタ', '米・麺・パスタ'),
('その他', 'その他'),
]
name = models.CharField(max_length=100, unique=True, help_text="食材名を入力してください") # 食材名
reading = models.CharField(max_length=100, help_text="食材の読み方を入力してください") # 読み方
type = models.CharField(max_length=50, choices=TYPE_CHOICES, help_text="食材の種類を選択してください") # 種類
def __str__(self):
return self.name
🗂 E-R図(モデルの関係)
以下ではモデルを扱うので↓の図を参考に!
🧩 serializers.py の記述
レシピやカテゴリ、食材のモデルをJSONに変換するために、以下のように serializers.py
を記述しました👇
from rest_framework import serializers
from .models import Recipe, Category
from ingredients.models import Ingredient
from ingredients.serializers import IngredientSerializer
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = '__all__'
class RecipeSerializer(serializers.ModelSerializer):
ingredients = serializers.PrimaryKeyRelatedField(many=True, queryset=Ingredient.objects.all())
categories = serializers.PrimaryKeyRelatedField(many=True, queryset=Category.objects.all())
class Meta:
model = Recipe
fields = '__all__'
🔍 解説:RecipeSerializer のポイント
-
ingredients
とcategories
はどちらもManyToManyField
なので、PrimaryKeyRelatedField
を使用し、ネストして使用しています。 -
many=True
を付けることで、複数のデータ(リスト形式)として扱うように指定 -
queryset=Model.objects.all()
で、関連モデルを正しく取得できるようにしています
ネストって?
class RecipeSerializer(serializers.ModelSerializer):
ingredients = IngredientSerializer(many=True, read_only=True)
categories = CategorySerializer(many=True, read_only=True)
class Meta:
model = Recipe
fields = '__all__'
🔧 一部のフィールドだけ指定する例
開発中などで表示項目を絞りたい場合は、次のように fields
にリストで明示的に書くことも可能です👇
class RecipeSerializer(serializers.ModelSerializer):
class Meta:
model = Recipe
fields = ['id', 'name', 'url', 'ingredients', 'categories']
🧐 なぜ一部フィールドにするのか?
-
不要なデータを省ける
→ 通信効率の向上、見やすさUP -
セキュリティのため
→ ユーザー情報など、外に出したくない情報は除外 -
データの簡潔化
→ クライアント側での処理が楽になる!
📦 例:フィールドを絞ったレスポンス
{
"id": 1,
"name": "鶏むね肉の照り焼き",
"url": "https://youtube.com/example",
"ingredients": [
{ "id": 1, "name": "鶏むね肉", "reading": "とりむねにく", "type": "肉" },
{ "id": 2, "name": "醤油", "reading": "しょうゆ", "type": "調味料" }
],
"categories": [
{ "id": 1, "name": "主菜" }
]
}
➡️ すっきりして見やすい!
ただし、thumbnail
などが含まれないため、必要に応じてフィールドを調整しましょう。
💬 まとめと感想
初めてDRFのシリアライザーを触ってみましたが、
正直、**「もっと早く知っておけばよかった…」**というレベルの便利さでした。
レシピ提案アプリ開発記事一覧はこちらから ↓