Python+Django REST FrameworkでAPIを作ってみた
環境構築
インストール
pip install Django
pip install djangorestframework
Djangoのプロジェクトを作成
django-admin startproject myproject .
Djangoのアプリケーションを作成
django-admin startapp myapp
VS Code用のデバッグ設定
launch.jsonに以下の記述をしておけば、F5押すだけで「manage.py runserver」を実行してくれます。
{
// IntelliSense を使用して利用可能な属性を学べます。
// 既存の属性の説明をホバーして表示します。
// 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}\\manage.py",
"args": [
"runserver"
],
"console": "integratedTerminal"
}
]
}
VS Code用のデバッグ設定(anaconda用)
settings.jsonに以下を追記すると、デバッグ実行時に自動でactivateしてくれます。
一旦「conda deactivate」すると、次にデバッグ実行してもactivateしてくれないようです。
{
"python.pythonPath": "C:\\Users\\ababa51515\\Anaconda3\\envs\\my_python_env\\python.exe"
}
settings.pyの編集
INSTALLED_APPS = [
'rest_framework', # 追加
'myapp', # 追加
]
マイグレーション
マイグレーションファイルの作成
python manage.py makemigrations
マイグレーションの実行
python manage.py migrate
マイグレーションの取消
python manage.py migrate myapp zero
管理者ユーザーの作成
python manage.py createsuperuser
管理サイトへのアクセス
python manage.py runserver
http://127.0.0.1:8000/admin にアクセスし、
python manage.py createsuperuser で作成したユーザ、パスワードでログインする。
モデル
\myproject\myapp\models.pyを削除してmodelsフォルダを作成し、その中にmodelを作成していきます。
from .pokemon import Pokemon
from .pokemon_name import PokemonName
こんな感じにしました。
from django.db import models
class Pokemon(models.Model):
class Meta:
db_table = 'pokemon'
ordering = ['order']
verbose_name = verbose_name_plural = 'ポケモン'
id = models.CharField(primary_key=True, max_length=5)
no = models.IntegerField(verbose_name='No')
is_default = models.BooleanField(verbose_name='デフォルトフォルム')
def __str__(self):
return str(self.no)
from django.db import models
from . import Pokemon
class PokemonName(models.Model):
class Meta:
db_table = 'pokemon_name'
ordering = ['pokemon_id', 'local_language_id']
verbose_name = verbose_name_plural = 'ポケモン名'
constraints = [
models.UniqueConstraint(
fields=["pokemon_id", "local_language_id"],
name="unique_pokemon_name"
),
]
id = models.CharField(primary_key=True, max_length=7)
local_language_id = models.IntegerField(verbose_name='言語')
name = models.CharField(verbose_name='ポケモン名', max_length=10)
form_name = models.CharField(verbose_name='フォルム名', max_length=20, null=True, blank=True)
pokemon = models.ForeignKey(Pokemon, verbose_name='ポケモン', on_delete=models.CASCADE)
def __str__(self):
name = self.name
form_name = '' if not self.form_name else '({})'.format(self.form_name)
return name + form_name
\myproject\myapp\admin.pyに記述する事で、管理者サイトからデータの更新・参照等ができるようになります。
from django.contrib import admin
from api.models import Pokemon, PokemonName
admin.site.register(Pokemon)
admin.site.register(PokemonName)
前述のマイグレーションを実行する事で、modelに応じたテーブルが作成されます。
シリアライザ
serializerもserializersフォルダを作成し、serializerを作成していきます。
from .pokemon_serializer import PokemonSerializer, PokemonListSerializer
from .pokemon_name_serializer import PokemonNameSerializer, PokemonNameListSerializer
from rest_framework import serializers
from ..models import Pokemon, PokemonName
class PokemonSerializer(serializers.ModelSerializer):
class Meta:
model = Pokemon
fields = ['id', 'no', 'is_default']
class PokemonListSerializer(serializers.ListSerializer):
child = PokemonSerializer()
from rest_framework import serializers
from ..models import Pokemon, PokemonName
class PokemonNameSerializer(serializers.ModelSerializer):
pokemon_no = serializers.ReadOnlyField(source='pokemon.no', read_only=True)
class Meta:
model = PokemonName
fields = ['id', 'local_language_id', 'name', 'form_name', 'pokemon_id', 'pokemon_no']
class PokemonNameListSerializer(serializers.ListSerializer):
child = PokemonNameSerializer()
ビュー
viewsフォルダを作成し、viewを作成していきます。
from .pokemon_view import PokemonAPIView, PokemonListAPIView
from .pokemon_name_view import PokemonNameAPIView, PokemonNameListAPIView
from django.http import Http404
from rest_framework import status, views
from rest_framework.response import Response
from ..models import Pokemon
from ..serializers import PokemonSerializer, PokemonListSerializer
class PokemonListAPIView(views.APIView):
def get(self, request, format=None):
pokemons = Pokemon.objects.all()
serializer = PokemonListSerializer(pokemons)
return Response(serializer.data, status.HTTP_200_OK)
class PokemonAPIView(views.APIView):
def get(self, request, pk, format=None):
try:
pokemon = Pokemon.objects.get(pk=pk)
except Pokemon.DoesNotExist:
raise Http404("data not found")
serializer = PokemonSerializer(pokemon)
return Response(serializer.data, status.HTTP_200_OK)
from django.http import Http404
from rest_framework import status, views
from rest_framework.response import Response
from ..models import Pokemon, PokemonName
from ..serializers import PokemonNameSerializer, PokemonNameListSerializer
class PokemonNameListAPIView(views.APIView):
def get(self, request, format=None):
print(request.query_params)
local_language_id = request.query_params.get('local_language_id')
if local_language_id:
pokemonNames = PokemonName.objects.filter(
local_language_id=local_language_id
)
name = request.query_params.get('name')
if name:
pokemonNames = PokemonName.objects.filter(
name__icontains=name
)
serializer = PokemonNameListSerializer(pokemonNames)
return Response(serializer.data, status.HTTP_200_OK)
class PokemonNameAPIView(views.APIView):
def get(self, request, pk, format=None):
try:
pokemonName = PokemonName.objects.get(pk=pk)
except Pokemon.DoesNotExist:
raise Http404("data not found")
serializer = PokemonNameSerializer(pokemonName)
return Response(serializer.data, status.HTTP_200_OK)
Urls.py
myappのUrls.py
from django.urls import path
import myapp.views as views
urlpatterns = [
path('pokemons/', views.PokemonListAPIView.as_view()),
path('pokemons/<pk>/', views.PokemonAPIView.as_view()),
path('pokemon-names/', views.PokemonNameListAPIView.as_view()),
path('pokemon-names/<pk>/', views.PokemonNameAPIView.as_view()),
]
myprojectのUrls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('myapp.urls'))
]
実行
起動後、以下でアクセスできます。
http://127.0.0.1:8000/api/pokemons/1
http://127.0.0.1:8000/api/pokemon-names/?name=ピカチュウ
ディスカッション
コメント一覧
まだ、コメントがありません