LoginSignup
3
2

More than 3 years have passed since last update.

[Django][RESTframework]追加、更新、取得の簡単な動的APIを作成する 備忘録

Last updated at Posted at 2021-03-05

前書き

すごく遠回りしながらなんとか作成できたAPIについて備忘録を残す。

今回作ったAPIは以下のようになる

# ユーザーの登録
http://127.0.0.1:8000/v1/user/

# pk=1 のユーザー情報を更新   
http://127.0.0.1:8000/v1/user/1/

# pk=2 のユーザー情報を取得
http://127.0.0.1:8000/v1/user/2/affinity

準備

プロジェクト名:project
アプリ名 :api

構成

└─project
   ├─api
   │ ├─migrations
   │ │ └─..
   │ ├─__init__.py
   │ ├─apps.py
   │ ├─models.py
   │ ├─serializer.py
   │ ├─urls.py
   │ └─views.py
   ├─project
   │ ├─__init__.py
   │ ├─asgi.py
   │ ├─settings.py
   │ ├─urls.py
   │ └─wsgi.py
   ├─db.sqlite3
   └─manage.py

プロジェクト作成

$ django-admin startproject project 
$ cd project
$ python manage.py startapp api

$ brew install mysql
$ pip install pymysql
$ pip install djangorestframework
$ pip install django-filter

$ mysql.server start 
# mysql.server stop でサーバー停止

#MySQLに入る
$ mysql -u root

MySQLの操作

mysql> show databases;
mysql> create database sample;
mysql> show databases;
mysql> exit

manage.py

manage.py
import pymysql #追加
pymysql.install_as_MySQLdb() #追加
$ python manage.py migrate

$ mysql -u root

mysql> use sample;
mysql> show tables;
mysql> exit

settings.py

settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'api',            #追加
    'rest_framework', #追加
    'django_filters', #追加
]

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'sample',  # 作成したデータベース名
        'USER': 'root',  # ログインユーザー名
        'HOST': '',
        'PORT': '',
    }
}

# ペジネーション
REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 5
}


LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'

models.py

最初にモデルを作成する
データベースに保存する内容を記述

models.py
from django.db import models

"""
CharField (文字列が入る)文字数制限必要
TextField(文章が入る)
ImageField(写真ファイルが入る)
FileField(不特定のファイルが入る)
IntegerField(数値が入る)オーバーフロー注意
BooleanField(True/False)が入る *いわゆるフラッグ
DateField(日付が入る)
DateTimeField(日時が入る)
ForeignKey(外部キー) *一対多のリレーションになる。(言葉だけでも覚えておきましょう!)
ManyToManyField(複数の外部キーが入る) *多対多のリレーションになる
OneToOneField(外部キー) *一対一のリレーションになる
"""
class BaseAPI(models.Model):

    first_name = models.CharField(max_length=32)
    last_name = models.CharField(max_length=32)

    class Meta:
        verbose_name_plural = "ベースAPI"

serializer.py

Modelに対してデータを適切な形にして入力、出力するもの
-[参考サイト6]

serializer.py
# coding: utf-8
from .models import BaseAPI
from rest_framework import serializers

class BaseAPISerializer(serializers.ModelSerializer):

    class Meta:
        model = BaseAPI
        fields = (
            'first_name',
            'last_name'
        )

views.py

Viewの設定についてはここを参照

クラス 操作
CreateAPIView 登録(POST)
ListAPIView 一覧取得(GET)
RetrieveAPIView 取得(GET)
UpdateAPIView 更新(PUT、PATCH)
DestroyAPIView 削除(DELETE)

-[参考サイト3]

views.py
# coding: utf-8
from .models import BaseAPI
from .serializer import BaseAPISerializer
from rest_framework import generics


class BaseAPIViewSet_POST(generics.CreateAPIView):
    queryset = BaseAPI.objects.all()
    serializer_class = BaseAPISerializer


class BaseAPIViewSet_PUT(generics.UpdateAPIView):
    queryset = BaseAPI.objects.all()
    serializer_class = BaseAPISerializer


class BaseAPIViewSet_GET(generics.RetrieveAPIView):
    queryset = BaseAPI.objects.all()
    serializer_class = BaseAPISerializer

project/urls.py

v1は慣習でAPIのバージョンを表すそう Ver 1.0.1みたいな

urls.py
"""プロジェクト名 URL Configuration

'urlpatterns'リストはURLをビューにルーティングします。
詳細は以下を参照してください。
https://docs.djangoproject.com/en/3.1/topics/http/urls/
例を紹介します。
関数ビュー
    1. インポートの追加: from アプリ名 import views
    2. urlpatternsにURLを追加する: path('', views.home, name='home')
クラスベースのビュー
    1. インポートの追加: from 他のアプリ名.views import Home
    2. urlpatternsにURLを追加する: path('', Home.as_view(), name='home')
別の URLconf を含む
    1. include() 関数をインポートします: from django.urls import include, path
    2. urlpatternsにURLを追加する: path('blog/', include('blog.urls')
"""

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

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

api/urls.py

動的なルーティングを行いたい場合
< str:pk > と記述する 

app/urls.py
# coding: utf-8
from django.urls import path
from .views import BaseAPIViewSet_POST, BaseAPIViewSet_PUT, BaseAPIViewSet_GET

app_name = 'api'
urlpatterns = [
    path('user/', BaseAPIViewSet_POST.as_view(), name='POST'),
    path('user/<str:pk>/', BaseAPIViewSet_PUT.as_view(), name='PUT'),
    path('user/<str:pk>/affinity', BaseAPIViewSet_GET.as_view(), name='GET'),
]
$ python manage.py runserver 
# ユーザーの登録
http://127.0.0.1:8000/v1/user/

スクリーンショット 2021-03-05 15.09.51.png

# pk=1 のユーザー情報を更新 
# (存在しないpkを指定するとサイトにアクセスできないと表示される)
http://127.0.0.1:8000/v1/user/1/

# pk=2 のユーザー情報を取得
# (存在しないpkを指定するとサイトにアクセスできないと表示される)
http://127.0.0.1:8000/v1/user/2/affinity

これで完成

もしURLのpkを取得したい場合は
この記事
の書き方を参照

参考サイト

1, Django REST Framework の使い方メモ
2, Django REST Frameworkを使って爆速でAPIを実装する
3, DRFのGeneric viewの使い方
4, Django REST framework カスタマイズ方法 - チュートリアルの補足
5, Django 開発者への道① ~ Modelsを理解する ~
6, Django REST frameworkで学んだことをまとめてみた

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