0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Django REST frameworkでAPIを作成する

Last updated at Posted at 2023-04-06

Django REST frameworkでAPIを作成する

備忘録
間違い等ありましたらご指摘いただけると幸いです

この記事を読んだら

  • Django REST framework(drf)で簡単なAPIを作成できる

Djangoとかdrfについての説明は省きます

1. 環境構築

実行環境

Python 3.10.4
Django 4.1.4
rest_framework 3.14.0

1.1. ライブラリのインストール

# poetry
$ poetry add django
$ poetry add djangorestframework

# pip
$ pip install django
$ pip install djangorestframework

1.2. Djangoプロジェクト作成

Djangoにはプロジェクトとアプリがあり、アプリは何かしらの処理を行うwebアプリケーションのことで、アプリをまとめたものがプロジェクトである。
プロジェクトを作成する

$ django-admin startproject <project_name>

このコマンドでデータベースの設定やDjangoのオプション、アプリケーションの設定などを定義するファイルが自動生成された。
現時点でファイル構成は以下のようになる。

<path>/<project_name>/
    manage.py
    <project_name>/
        __init__.py
        settings.py
        urls.py
        asgi.py
        wsgi.py

これでプロジェクトが完成した。次ステップでmanage.pyを実行するのでディレクトリを移動しておく。

$ cd <project_name>

次はアプリを作成する

1.3. Djangoアプリ作成

manage.pyでアプリを作成する

$ python manage.py startapp <app_name>

ディレクトリ構成は以下のようになる

<project_name>/
    manage.py
    <project_name>/
        __init__.py
        settings.py
        urls.py
        asgi.py
        wsgi.py
    <app_name>/
        __init__.py
        admin.py
        apps.py
        migrations/
            __init__.py
        models.py
        tests.py
        views.py

1.4. 設定ファイルの修正

アプリを作ったので設定ファイル(<project_name>/settings.py)に追記する

project_name/settings.py
...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    '<app_name>', # アプリ追加
    'rest_framework', # drfも追加する
]
...

2. APIを作る

顧客管理APIを試しに作ってみる。

必要な機能は

  • 顧客登録(POST)
  • 顧客情報閲覧(GET)
  • 顧客情報の修正(PATCH)
  • 顧客情報の削除(DELETE)

基本的に編集するのは<app_name>の下の

  • models.py
  • serializers.py
  • views.py
  • urls.py

の四つ。各ファイルの役割を説明する

models.py

DBのレイアウトを定義する。
APIがDBを必要としない場合はこのファイルはいじらない
今回は顧客をDBに登録したいので必要。

serializers.py

シリアライザーを定義する。
シリアライズはクエリセットやモデルインスタンスなどの複雑なデータをJSONやXMLなどのコンテンツタイプに変換する処理。
シリアライザーはデシリアライズ(シリアライズの逆)も提供している。

views.py

リクエスト(GET, POST, PUT, PATCH, DELETE)に対する振る舞いを定義する。APIの本体。

urls.py

APIのurlを定義する。

2.1. ファイル作成

<app_name>フォルダに

  • serializers.py
  • urls.py

を作成する

2.2. コードを書く

2.2.1. models.py

次のようなテーブルを作る

カラム名 Null可否 デフォルト 備考
created_at DATETIME 現在時刻 インスタンスが作成された時間
updated_at DATETIME データが更新された時間
user_id STRING uuid自動生成 ユーザーid。PK。uuidを自動生成する
name STRING ユーザーの名前
age INTEGER ユーザーの年齢
gender INTEGER ユーザーの性別。男、女、その他を選択できるようにする

models.pyは以下のようになる。

project_name/app_name/models.py
from django.db import models
import uuid
# Create your models here.

# モデルを作成するのにmodels.Modelを継承する
class Customer(models.Model):
    # 性別の選択肢を作成するリスト
    GENDER = [
        (0, ''),
        (1, ''),
        (2, 'その他')
    ]
    # フィールドを定義する
    created_at = models.DateTimeField(auto_now_add=True, null=False)
    updated_at = models.DateTimeField(auto_now=True)
    user_id = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False, null=False)
    name = models.CharField(max_length=100, null=False)
    age = models.IntegerField()
    gender = models.IntegerField(choices=GENDER)

    class Meta:
        # created_atで並べる
        ordering = ['created_at']

基本的にフィールドを型名Fieldで定義していく。必要に応じてオプションを追加する
コード内のオプションはそれぞれ
null : nullを許可するかどうか
auto_now_add : インスタンス作成時の時間を追加する
auto_now : インスタンスを保存するたびに時間を更新する
default : デフォルト値
primary_key : pkであるかどうか
editable : 編集可能かどうか
max_length : 最大の長さ(CharFieldはこれがないとエラーになる)
choices : 選択肢を提供する
となっている。他にも色々とあるのでモデルフィールドリファレンスを参照。

2.2.2 serializers.py

serializers.pyの中ではレスポンスで表示するカラムを設定する。

project_name/app_name/serializers.py
from rest_framework import serializers
from .models import Customer

# シリアライザー作成はserializers.ModelSerializerを継承する
class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        # 先ほど作成したモデルを指定
        model = Customer
        # 読み取り専用にするフィールドを指定
        read_only_fields = ('user_id', 'created_at', 'updated_at')
        # read_only以外の全てのフィールドをシリアライズする
        fields = '__all__'

2.2.3 views.py

リクエストに対して色々処理を加えて返すこともできるが、ここではシンプルにCRUDができるようなAPIを作成する。

project_name/app_name/views.py
from .models import Customer
from .serializers import CustomerSerializer
from rest_framework import generics

# Create your views here.

# 一覧表示&顧客登録ができるview
class CustomerList(generics.ListCreateAPIView):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer

# 顧客の詳細閲覧&情報の削除&修正ができるview
# このviewはuser_idをパラメータに指定する予定であり、顧客を特定しないとできないような動作を行う
class CustomerDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer

generics.ListCreateAPIViewは一覧表示・インスタンス作成ができるAPI、generics.RetrieveUpdateDestroyAPIViewは特定のインスタンスの閲覧・削除・修正ができるAPIを作成できる。

2.2.4 urls.py

APIのurlを設定する。

project_name/app_name/urls.py
from django.urls import path
from . import views

urlpatterns = [
    # 一覧表示・インスタンス作成ができるAPIのエンドポイント
    path('customers/', views.CustomerList.as_view()),
    # pk(user_id)を指定してインスタンスの閲覧・削除・修正ができるAPIのエンドポイント
    # 例:customers/d20dbce4-b092-4047-b00b-79e8b829b140
    path('customers/<str:pk>/', views.CustomerDetail.as_view()),
]

<project_name>/urls.pyも変更する。

project_name/urls.py
from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
    # 追加、APIのurlはdomain/api/<api_name>となる
    path('api/', include('drf_app.urls')),
]

2.3. マイグレーション

データベースへのマイグレーションを行う。

# マイグレーションファイルの作成
$ python manage.py makemigrations
# マイグレート
$ python manage.py migrate

2.4. 実行

サーバーを立ち上げる。

$ python manage.py runserver

エラーが出ずサーバーが立ち上がったら成功。次のようなログが出るはず

Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
April 06, 2023 - 14:28:53
Django version 4.1.4, using settings '<project_name>.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

http://localhost:8000/api/customer/にアクセスすると次のような画面になる。
Screenshot 2023-04-06 at 23.27.36.png
値を入れてPOSTすると...
Screenshot 2023-04-06 at 23.30.38.png
ちゃんと登録できた。
Screenshot 2023-04-06 at 23.30.58.png
http://localhost:8000/api/customer/に再度アクセスすると、POSTしたデータが表示されているのがわかる。
Screenshot 2023-04-06 at 23.33.58.png
user_idがわかったのでhttp://localhost:8000/api/customer/6835dd62-5e2e-4a76-96a0-3cb61873693dにアクセスしてみると
Screenshot 2023-04-06 at 23.31.20.png
詳細を取得することができた。この画面からPUT、DELETEもできる。

権限も特に付けてないのでcurl経由とかでもデータを取得できる。

$ curl http://127.0.0.1:8000/api/customers/6835dd62-5e2e-4a76-96a0-3cb61873693d/
>> {"user_id":"6835dd62-5e2e-4a76-96a0-3cb61873693d","created_at":"2023-04-06T14:30:45.073879Z","updated_at":"2023-04-06T14:30:45.073929Z","name":"江田島平八","age":33,"gender":0}

ありがとうございました。

参考

drf公式ドキュメント
Django公式ドキュメント

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?