Closed8

Django REST FrameworkでAPIを作ってdocker-composeで動かす

not75743not75743

最初の準備

Dockerfile

FROM python:3.11.4-bookworm
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/

RUN apt-get update && apt-get install -y netcat-traditional

COPY ./entrypoint.sh /usr/src/app/entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]

requirements.txt

Django == 4.1
psycopg2 == 2.9.6
djangorestframework == 3.14.0

docker-compose.yaml

version: '3.9'
 
services:
  db:
    image: postgres
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_PASSWORD=postgres
  web:
    environment:
      - DATABASE=postgres
      - DB_HOST=db
      - DB_PORT=5432
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

entrypoint.sh

#!/bin/sh

if [ "$DATABASE" = "postgres" ]
then
    echo "Waiting for postgres..."

    while ! nc -z $DB_HOST $DB_PORT; do
      sleep 0.1
    done

    echo "PostgreSQL started"
fi

exec "$@"
not75743not75743

アプリケーション作成

# プロジェクト作成
docker compose run web django-admin startproject todo .

# アプリケーションを作る
docker compose run web python manage.py startapp todoapp
not75743not75743

マイグレーションまで

モデル作成

from django.db import models

class ToDo(models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField()
    completed = models.BooleanField(default=False)

settings.py変更

データベース情報の編集

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'postgres',
        'USER': 'postgres',
        'PASSWORD': 'postgres',
        'HOST': 'db',
        'PORT': '5432',
    }
}

todoアプリケーションを追加

python
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
+   'todoapp',
]

検証のためすべてのアクセスを許可

ALLOWED_HOSTS = ["*"]

マイグレーション

# migrationファイル作成
docker compose run web python manage.py makemigrations todoapp

# migrate
docker compose run web python manage.py migrate
not75743not75743

View,URLを編集する

views.py

from rest_framework import viewsets
from .models import ToDo
from .serializers import ToDoSerializer

class ToDoViewSet(viewsets.ModelViewSet):
    queryset = ToDo.objects.all()
    serializer_class = ToDoSerializer

urls.py(app)

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ToDoViewSet

router = DefaultRouter()
router.register(r'todos', ToDoViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

urls.py(project)

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('todoapp.urls')),
]
not75743not75743

管理者ユーザ作成

$ docker compose run web python manage.py createsuperuser

起動

$ docker compose up -d
$ docker compose ps
not75743not75743

アクセス

管理者ページ

http://<domain>:8000/admin

API

GET

一覧表示

$ curl -s -X GET http://localhost:8000/api/todos/ | jq
[
  {
    "id": 1,
    "title": "Test todo",
    "description": "This is a test",
    "completed": false
  }
]

POST

新規追加

$ curl -X POST -H "Content-Type: application/json" -d '{"title":"Test2", "description":"Test2"}' http://localhost:8000/api/todos/
{"id":2,"title":"Test2","description":"Test2","completed":false}

PUT

更新

$ curl -X PUT -H "Content-Type: application/json" -d '{"title":"update", "description":"update"}' http://localhost:8000/api/todos/4/

DELETE

削除

$ curl -X DELETE http://localhost:8000/api/todos/1/
このスクラップは2023/07/09にクローズされました