DEV Community

niwoshi for Takenoko Tech LLC.

Posted on

Django REST frameworkの初期セットアップ

Django REST framework(以下DRF)でバックエンドを構築する際の初期設定をメモ代わりに書いておきます。
(書かないと無限に忘れるので・・・)

プロジェクトの作成

プロジェクト名はtutorialとしておきます。
ディレクトリを作成して仮想環境(venv)が導入されている前提です。

まずはrequirements.txtに必要最低限のライブラリのみ書いておきます。
よく使うライブラリもこのタイミングで入れていいと思います。

django
djangorestframework
Enter fullscreen mode Exit fullscreen mode

必要パッケージのインストール

pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

Djangoプロジェクトの作成をコマンドで行います。
この辺は完全に好みだと思うのですが、プロジェクト名/プロジェクト名/settings.pyみたいにプロジェクト名が二重にネストするのがちょっと気持ち悪いので、この設定ファイルなどがあるディレクトリ名をconfigにするために、下記のようにDjangoプロジェクトを作成します。
仮想環境を入れたプロジェクトファイル下で下記のコマンドを実行します。

django-admin startproject config .
Enter fullscreen mode Exit fullscreen mode

プロジェクト全体のディレクトリ構成は下記の様になります。

tutorial
├─ venv
├─ requirements.txt
├─ manage.py
└─ config
   ├─ __init__.py
   ├─ asgi.py
   ├─ settings.py
   ├─ urls.py
   └─ wsgi.py
Enter fullscreen mode Exit fullscreen mode

機能的にはtutorial/tutorialになってもなんら問題無いのでこの辺は完全に好みです。むしろこっちの方が面倒。
動作チェックはDRFとして動いて欲しいので、適当なモデルを作成してから行います。

アプリケーションの追加

試しにTodoを管理するアプリケーションを想定して構築してみます。
DRFはAPIエンドポイントとして運用される想定なので、一応バージョニングを意識して

  • APIエンドポイント用のアプリケーション(ここではapiv1
  • モデル用のアプリケーション(ここではtodos

を分離しておきます。
manage.pyでアプリケーションを作成しておきます。

python manage.py startapp apiv1
python manage.py startapp todos
Enter fullscreen mode Exit fullscreen mode

ここで初期設定もかねて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",)

...
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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)

Enter fullscreen mode Exit fullscreen mode

一応管理画面を確認しておきたいので念のためDBを更新してからcreatesuperuserで管理ユーザーを作成しておきます。

python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
Enter fullscreen mode Exit fullscreen mode

ここまでやれば管理画面からモデルを操作できるので、動作に不安のある場合はこの辺で新規作成などしてみても良いと思うます。

シリアライザの作成

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",
        ]

Enter fullscreen mode Exit fullscreen mode

ビューの作成

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

Enter fullscreen mode Exit fullscreen mode

ルーティングの設定

大体の機能は実装できたので、ルーティングの設定をしておきます。
まずは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))]

Enter fullscreen mode Exit fullscreen mode

routerにtodosを登録する際にbasename="todos"と指定しているのは、django.urlsreverse関数で逆引きする際に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"))]

Enter fullscreen mode Exit fullscreen mode

ここまでやれば、APIとしては実装完了です。

動作チェック

DRFはデバッグモードではブラウザ上で色々確認出来ます。
試しにアクセスしてみると、何もないリストが返却されているのが確認出来ると思います。

Image description

POST用のフォームもあるので、そちらから追加して見るもヨシ、cURLなどで追加して見るもヨシです。

おわり

上記だけでCRUD操作ができるAPIが構築でき、管理画面も使いやすいしカスタマイズしやすいのがDRFの良さだと思います。
本来であれば認証まわりも実装すると思いますが、今回は簡略化のため省きました。
実際に実装する場合はDRFの設定(settings.py)とビューでの設定などが必要になると思います。

参考

Top comments (0)