niwoshi
Posted on January 20, 2022
Django REST framework(以下DRF)でバックエンドを構築する際の初期設定をメモ代わりに書いておきます。
(書かないと無限に忘れるので・・・)
プロジェクトの作成
プロジェクト名はtutorial
としておきます。
ディレクトリを作成して仮想環境(venv)が導入されている前提です。
まずはrequirements.txt
に必要最低限のライブラリのみ書いておきます。
よく使うライブラリもこのタイミングで入れていいと思います。
django
djangorestframework
必要パッケージのインストール
pip install -r requirements.txt
Djangoプロジェクトの作成をコマンドで行います。
この辺は完全に好みだと思うのですが、プロジェクト名/プロジェクト名/settings.py
みたいにプロジェクト名が二重にネストするのがちょっと気持ち悪いので、この設定ファイルなどがあるディレクトリ名をconfig
にするために、下記のようにDjangoプロジェクトを作成します。
仮想環境を入れたプロジェクトファイル下で下記のコマンドを実行します。
django-admin startproject config .
プロジェクト全体のディレクトリ構成は下記の様になります。
tutorial
├─ venv
├─ requirements.txt
├─ manage.py
└─ config
├─ __init__.py
├─ asgi.py
├─ settings.py
├─ urls.py
└─ wsgi.py
機能的にはtutorial/tutorial
になってもなんら問題無いのでこの辺は完全に好みです。むしろこっちの方が面倒。
動作チェックはDRFとして動いて欲しいので、適当なモデルを作成してから行います。
アプリケーションの追加
試しにTodoを管理するアプリケーションを想定して構築してみます。
DRFはAPIエンドポイントとして運用される想定なので、一応バージョニングを意識して
- APIエンドポイント用のアプリケーション(ここでは
apiv1
) - モデル用のアプリケーション(ここでは
todos
)
を分離しておきます。
manage.py
でアプリケーションを作成しておきます。
python manage.py startapp apiv1
python manage.py startapp todos
ここで初期設定もかねてconfig/settings.py
を編集します。
...
from pathlib import Path
from django.conf.locale.ja import formats as ja_formats
...
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"rest_framework",
"apiv1.apps.Apiv1Config",
"todos.apps.TodosConfig",
]
...
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = "ja"
TIME_ZONE = "Asia/Tokyo"
USE_I18N = True
USE_L10N = True
USE_TZ = True
ja_formats.DATE_FORMAT = "Y/m/d"
ja_formats.DATE_INPUT_FORMATS = ("%Y/%m/%d",)
ja_formats.DATETIME_FORMAT = "Y/m/d H:i:s"
ja_formats.DATETIME_INPUT_FORMATS = ("%Y-%m-%d %H:%M:%S",)
...
INSTALLED_APPS
の追記は、Django 3.2からAutomatic AppConfig discoveryで不要になったと聞いたのですが、自分の環境では何故か管理画面にモデルが表示されないので追記しています。
モデルの作成
models.pyの編集
何はともあれモデルがないと始まりません。
Todoモデルtodos/models.py
を作成していきます。
import uuid
from django.db import models
class Todo(models.Model):
class Meta:
db_table = "todo"
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=200)
checked = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
idをUUIDにしていますが、ここは好みです。(とはいえ、UUIDの方が推奨されそうですが・・・)
admin.pyの編集
モデルを作ったら管理画面で編集できる様にしておきたいです。
todos/admin.py
を編集します。
from django.contrib import admin
from .models import Todo
class TodoAdmin(admin.ModelAdmin):
fields = ["title", "checked"]
list_display = ("title", "checked", "id", "created_at", "updated_at")
admin.site.register(Todo, TodoAdmin)
一応管理画面を確認しておきたいので念のためDBを更新してからcreatesuperuser
で管理ユーザーを作成しておきます。
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
ここまでやれば管理画面からモデルを操作できるので、動作に不安のある場合はこの辺で新規作成などしてみても良いと思うます。
シリアライザの作成
DRF特有の存在であるシリアライザを作成します。
これはAPIの機能なのでapiv1/serializers.py
に作成します。
from rest_framework import serializers
from todos.models import Todo
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = [
"id",
"title",
"checked",
]
ビューの作成
API用のビューapiv1/views.py
を編集します。
from rest_framework import viewsets
from todos.models import Todo
from .serializers import TodoSerializer
class TodoViewSet(viewsets.ModelViewSet):
queryset = Todo.objects.all()
serializer_class = TodoSerializer
ルーティングの設定
大体の機能は実装できたので、ルーティングの設定をしておきます。
まずはapiv1/urls.py
を作成します。
from django.urls import path, include
from rest_framework import routers
from . import views
router = routers.DefaultRouter()
router.register("todos", views.TodoViewSet, basename="todos")
app_name = "apiv1"
urlpatterns = [path("", include(router.urls))]
routerに
todos
を登録する際にbasename="todos"
と指定しているのは、django.urls
のreverse
関数で逆引きする際にapiv1:todos-list
としたい為です。コレを指定していない場合はビューのqueryset
に登録したモデルの名称が採用されてapiv1:todo-list
と参照されてしまう様です。
今回はビューをModelViewSetで実装したのでルーティングが楽です。
あとはconfig/urls.py
を編集します。
from django.contrib import admin
from django.urls import path, include
urlpatterns = [path("admin/", admin.site.urls), path("api/v1/", include("apiv1.urls"))]
ここまでやれば、APIとしては実装完了です。
動作チェック
DRFはデバッグモードではブラウザ上で色々確認出来ます。
試しにアクセスしてみると、何もないリストが返却されているのが確認出来ると思います。
POST用のフォームもあるので、そちらから追加して見るもヨシ、cURLなどで追加して見るもヨシです。
おわり
上記だけでCRUD操作ができるAPIが構築でき、管理画面も使いやすいしカスタマイズしやすいのがDRFの良さだと思います。
本来であれば認証まわりも実装すると思いますが、今回は簡略化のため省きました。
実際に実装する場合はDRFの設定(settings.py)とビューでの設定などが必要になると思います。
参考
Posted on January 20, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
August 31, 2023
August 26, 2023