2
3

Djangoでapiを作ってみた

Posted at

はじめに

API作成を行ってみたいと思ったので、DjangoRestFrameworkを使って、とても簡単なapiを作成してみました。

APIとは
Application Programing Interfaceの略称で、ソフトウェアアプリケーションを連携させ、データや機能を共有させるためのインターフェイス(接続手段)をプログラムしたものです。

DjangoRestFrameworkとは
djangoでRestfulなAPIを作成するためのライブラリです。

Restfulとは
RESTと呼ばれるwebアプリケーションで持ちられる設計(アーキテクチャ)原則をのこと。Restfulとは、RESTというアーキテクチャで実装したwebアプリケーション等のことを指す(らしい、形容詞として使われている)

開発環境

  • IDE:pycharm
  • python:3.9
  • フレームワーク:django
  • DB:sqlite(djangoのデフォルトであるsqliteにしました。)
  • docker

最終的なディレクトリは下のようになりました。

.
├── ApiTest
│   ├── ApiTest
│   │   ├── __init__.py
│   │   ├── asgi.py
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   ├── db.sqlite3
│   ├── manage.py
│   └── storage
│       ├── __init__.py
│       ├── admin.py
│       ├── apps.py
│       ├── migrations
│       │   ├── 0001_initial.py
│       │   └── __init__.py
│       ├── models.py
│       ├── serializers.py
│       ├── tests.py
│       ├── urls.py
│       └── views.py
├── Dockerfile
├── docker-compose.yml
└── requirements.txt

今回は、まず仮想環境で開発をし、最後にdocker環境に移行してみました。

開発環境の準備

仮装環境を作ります。

python3 -m venv venv

仮装環境に入ります。

source -m venv venv

仮装環境に入った状態でdjangoをインストールします。

pip install django

次にdjangorestframeworkをインストールします。

pip install djangorestframework

以下のコマンドでプロジェクトを立ち上げます。

django-admin startproject ApiTest

以下のコマンドでアプリを立ち上げます。

python manage.py startapp storage

プロジェクトファイルの設定

クライアントからリクエストを受け取るサーバーを指定するために、プロジェクトディレクトリのsetting.pyを記述します。

ApiTest/setting.py
ALLOWED_HOSTS = ['*']

同じファイルで、djangorestframeworkを使うためにrest_frameworkを登録します。

ApiTest/setting.py
INSTALLED_APPS = [
    'storage.apps.StorageConfig',#追加
    'rest_framework',#追加
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

同じファイルでの日本語設定、標準の時刻を日本語に設定します。
こうすることで管理画面が日本語になり、レコード登録した際のタイムログが日本の標準時間になります。

ApiTest/setting.py
LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'

アプリでの設定

model.pyでモデルを作成します。今回は、Itemというモデルを作成しました。

models.py
from django.db import models

class Item(models.Model):
    name = models.CharField(max_length=255)
    cost = models.IntegerField()

admin.pyで管理者画面からレコードを操作できるようにします。

admin.py
from django.contrib import admin
from .models import Item #追加

admin.site.register(Item)追加

下のコマンドでマイグレーションを行います。

python manage.py makemigrations storage

マイグレーションとは、データベースに対して、変更を加えるための仕組みです。

マイグレーションをデータベースに適応します。(マイグレート)

python manage.py migrate

以下のコマンドでローカルサーバーを起動します。

python manage.py runserver

http://localhost:8000をブラウザで検索します。

スクリーンショット 2024-05-26 23.32.18.png

管理画面でレコードを入れる

スーパーユーザーを作成して、レコードを作成、編集してみます。

python manage.py createsuperuser

http://localhost:8000/adminで管理者画面に入ります。

スクリーンショット 2024-05-26 23.36.20.png

Itemsのとこを選択して、以下のようにレコードを追加してみます。

スクリーンショット 2024-05-26 23.39.23.png

スクリーンショット 2024-05-26 23.39.33.png

登録はできましたが、レコードの判別が一覧でできないようになっていました。
スクリーンショット 2024-05-26 23.40.51.png

これは、レコードを判別するための名前を設定していないからでした。
なので、models.pyで以下のコードを追加して、レコードを名前で判別できるにしました。

models.py
from django.db import models

class Item(models.Model):
    name = models.CharField(max_length=255)
    cost = models.IntegerField()

    #追加
    def __str__(self):
        return self.name

スクリーンショット 2024-05-26 23.42.06.png

API作成

ここからAPIを作成していこうと思います。
アプリケーションのディレクトリに、serializer.pyを書きます

serializer.py
from rest_framework import serializer
from .models import Item

class ItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = Item
        fields = '__all__'

シリアライザーとは、データを適切な形に変換して、入出力を行うためのクラスです。pythonがデータを扱うための橋渡し的な存在になります。

ここから、ItemモデルのAPIエンドポイントを指定させるためにviews.pyを指定します。

views.py
from rest_framework import viewsets
from .models import Item
from .serializers import ItemSerializer

class ItemViewSet(viewsets.ModelViewSet):

    queryset = Item.objects.all()
    serializer_class = ItemSerializer

viewsetsモジュールは、モデルに対するCURD機能を一括で設定できます。
querysetは、モデルのデータ一覧のことです。
serializer_classの部分は、モデルのデータの受け渡しを適切な形にするために設定しています。

urls.pyでルーティングを設定します。

storage/urls.py
from django.urls import path,include
from rest_framework.routers import DefaultRouter
from .views import ItemViewSet

router = DefaultRouter()
router.register('Item',ItemViewSet)

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

ルーティングとは、http等のリクエストに対して、どのように処理をさせるか経路を指定することです。
DefaultRouterでapiに対するリクエストのルーティング設定が行えます。

プロジェクトディレクトリ側で、アプリのエンドポイントを指定します。

Apitest/urls.py

from django.contrib import admin
from django.urls import path,include#includeを追加

urlpatterns = [
    path('admin/', admin.site.urls),
    path('storage/',include('storage.urls')),#追加
]

http://localhost:8000/storage/を検索して、が出てきたらapi作成は完了です!

スクリーンショット 2024-05-26 23.55.50.png

http://localhost:8000/storage/Item/を指定することでモデルのデータ一覧を見ることができます。

スクリーンショット 2024-05-27 0.10.03.png

おまけ

dockerに環境を移行

以下のコマンドで、requiremets.txtを生成

pip freeze > requirements.txt
requirements.txt
asgiref==3.8.1
Django==4.2.13
djangorestframework==3.15.1
sqlparse==0.5.0
typing_extensions==4.12.0

次にDockerfileを書きます。

FROM python:3.9

ENV PYTHONUNBUFFERED=1

ENV PYTHONDONTWRITEBYTECODE=1

WORKDIR /code/

COPY requirements.txt /code/

RUN pip install --no-cache-dir -r requirements.txt

COPY . /code/

#CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

CMDの部分は、今回ymlファイルを使うためコメントアウトしました。

docker-compose.ymlを記述します。

docker-compose.yml
version: '3'

services:
  web:
    build: .
    volumes:
      - .:/code
    working_dir: /code/ApiTest/
    ports:
      - 8000:8000
    command: python manage.py runserver 0.0.0.0:8000

コンテナに含めたくないものを.dockerignoreに記述します。

.dockerignore
venv
__pycache__
*.pyc
*.pyo
*.pyd
*.sqlite3
*.log

以下のコマンドでイメージとコンテナを同時に作成します。

docker compose up --build

ここでvenvファイルを消しても大丈夫です。

一応deactivateをコマンドで打ってディアクティベートしとくとスムーズに消せるかもしれません。

最後に

次はなんかしらのアプリケーションで連携させるようにしようと思います。

2
3
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
2
3