広告 プログラミング

【解説】Social OAuthによるアプリケーション連携(2/3)【Django REST framework】

※本ページには、プロモーション(広告)が含まれています。

悩んでいる人
悩んでいる人

ログイン情報を用いてユーザを識別できるWebサービスを作成したい。

ただし、新規にアカウントを作るのではなく、SNSなどの既存アカウントと連携した構成としたい。

また、モダンなフロントエンドを用いたいため、バックエンドはRESTfulな構成としたい。

こんなお悩みを解決します。

今回は、前回の続きとなり、バックエンド側の設定について解説します。

前回の記事では、全体構成とソーシャルログインを利用する上での準備作業について解説しています。詳しくは以下の記事を参考にしてください。

あわせて読みたい
【解説】Social OAuthによるアプリケーション連携(1/3)【Django REST framework】

続きを見る

実装結果

先に実装結果を確認したい方は、以下のリンクからGitHubへアクセスしてください。

https://github.com/yuruto-free/django-rest-framework/tree/v0.2.0

バックエンドの構築手順

バックエンドの構築手順の概要は以下のようになります。

  1. Django用の環境変数の設定
  2. 関連ライブラリのインストール
  3. プロジェクトの作成
  4. アプリケーションの作成
  5. 各種設定

今回はDockerを用いて環境構築を行っていますが、別の方法(pipenvなど)でも実施できるように、上記に示した順番で解説していきます。

今回、説明する内容のメインは「各種設定」部分のため、内容を先に確認したい場合、コチラをクリックしてください。

また、以下のようなディレクトリ構成を想定してます。


./
|-- docker-compose.yml
|-- LICENSE
|-- README.md
|-- wrapper.sh
|-- django/
|   |-- Dockerfile
|   |-- execute.sh
|   |-- README.md
|   |-- requirements.txt
|   |-- uwsgi.template
|   |-- sqlite/
│   |   `-- db.sqlite3
|   `-- src/
|       |-- manage.py
|       |-- accounts/
|       |   |-- admin.py
|       |   |-- apps.py
|       |   |-- models.py
|       |   |-- pipeline.py
|       |   |-- serializers.py
|       |   |-- tests.py
|       |   |-- urls.py
|       |   |-- views.py
|       |   |-- __init__.py
|       |   `-- migrations/
|       |       |-- 0001_initial.py
|       |       `-- __init__.py
|       `-- config/
|           |-- asgi.py
|           |-- define_module.py
|           |-- urls.py
|           |-- wsgi.py
|           |-- __init__.py
|           `-- settings/
|               |-- base.py
|               |-- development.py
|               |-- production.py
|               `-- __init__.py
|-- envs/
|   |-- django/
|   |   |-- .env
|   |   `-- README.md
|   |-- mysql/
|   |   |-- .env
|   |   `-- README.md
|   `-- react/
|       |-- .env
|       `-- README.md
|-- react/
|   |-- Dockerfile
|   |-- execute.sh
|   |-- public/
|   |   |-- favicon.ico
|   |   |-- index.html
|   |   |-- manifest.json
|   |   `-- robots.txt
|   `-- src/
|       |-- App.js
|       |-- App.test.js
|       |-- index.js
|       |-- reportWebVitals.js
|       |-- setupTests.js
|       `-- components
|           |-- login-logout.js
|           `-- user-info.js
`-- static
    `-- .gitkeep

Django用の環境変数の設定

GitHubで公開しているDocker環境を利用する場合と利用しない場合で設定する環境変数が異なるため、それぞれ分けて説明します。

GitHubで公開しているDocker環境を利用する場合

下記に示す内容をenvs/django/.envファイルとして保存します。

具体的な環境変数の意味は、後述する表を参考にしてください。

DJANGO_APP_ENV=development
DJANGO_SECRET_KEY=78f=abcdefghijklmnopqrstuvwxyz0123456789
DJANGO_WWW_VHOST=*
DJANGO_SUPERUSER_USERNAME=superuser
DJANGO_SUPERUSER_EMAIL=superuser@drf.com
DJANGO_SUPERUSER_PASSWORD=superuser@password
DJANGO_SOCIAL_GOOGLE_OAUTH2_KEY=google-oauth2-key
DJANGO_SOCIAL_GOOGLE_OAUTH2_SECRET=google-oauth2-secret

また、下記に示す内容をenvs/mysql/.envファイルとして保存します。

ただし、今回、コチラの内容は利用しません。(Dockerを動かす上で必要になるため)

MYSQL_ROOT_PASSWORD=rootpassword
MYSQL_DATABASE=django
MYSQL_USER=django
MYSQL_PASSWORD=restframework

GitHubで公開しているDocker環境を利用しない場合

下記に示す内容を.envファイルとして保存します。(保存先は各自の環境に揃えてください)

DJANGO_APP_ENV=development
DJANGO_SECRET_KEY=78f=abcdefghijklmnopqrstuvwxyz0123456789
DJANGO_WWW_VHOST=*
DJANGO_SUPERUSER_USERNAME=superuser
DJANGO_SUPERUSER_EMAIL=superuser@drf.com
DJANGO_SUPERUSER_PASSWORD=superuser@password
DJANGO_SOCIAL_GOOGLE_OAUTH2_KEY=google-oauth2-key
DJANGO_SOCIAL_GOOGLE_OAUTH2_SECRET=google-oauth2-secret
LANGUAGE_CODE=ja
TZ=Asia/Tokyo
FRONTEND_PORT=3000
DB_HOST=locahost
DB_PORT=3306
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci

それぞれの環境変数の説明

それぞれの環境変数(15個)の位置づけを以下に示します。ここで、DJANGO_SECRET_KEYDJANGO_SOCIAL_GOOGLE_OAUTH2_KEYDJANGO_SOCIAL_GOOGLE_OAUTH2_SECRETは、ご自身の環境に合わせて設定する必要があります。

環境変数名位置づけ
DJANGO_APP_ENVDjangoの実行モードを判断する際に利用する。設定値は以下の2つがあるが、今回はdevelopmentを設定する。
・development
・production
DJANGO_SECRET_KEYセキュリティに関する情報を生成する際に利用する。このキーはコチラのサイトで生成できる。
DJANGO_WWW_VHOSTアクセス可能なホスト名を指定する。複数指定する場合はカンマ区切りで指定する。(DJANGO_APP_ENV=productionの時のみ有効)
DJANGO_SUPERUSER_USERNAMEスーパーユーザのユーザ名
DJANGO_SUPERUSER_EMAILスーパーユーザのメールアドレス
DJANGO_SUPERUSER_PASSWORDスーパーユーザのパスワード
DJANGO_SOCIAL_GOOGLE_OAUTH2_KEYGoogle-OAuth2で利用するクライアントID
Google Developer Consoleで確認したクライアントIDを指定する。
DJANGO_SOCIAL_GOOGLE_OAUTH2_SECRETGoogle-OAuth2で利用するクライアントシークレット
Google Developer Consoleで確認したクライアントシークレットを指定する。
LANGUAGE_CODE言語コード
TZタイムゾーン
FRONTEND_PORTフロントエンドのポート番号。今回は3000番を使用する。
DB_HOSTデータベースへのアクセス先。(DJANGO_APP_ENV=productionの時のみ有効)
DB_PORTデータベースへアクセスする際のポート番号。(DJANGO_APP_ENV=productionの時のみ有効)
DB_CHARSETデータベースの文字コード。(DJANGO_APP_ENV=productionの時のみ有効)
DB_COLLATIONデータベースにおける照合順序。(DJANGO_APP_ENV=productionの時のみ有効)
Djangoで利用する環境変数設定

関連ライブラリのインストール

GitHubで公開しているDocker環境を利用する場合と利用しない場合で手順が異なるため、それぞれ分けて説明します。

GitHubで公開しているDocker環境を利用する場合

トップディレクトリで、以下のコマンドを実行し、コンテナイメージを作成します。

# shell scriptに実行権限を与える
chmod +x wrapper.sh
# Docker Imageを作成する
./wrapper.sh build

GitHubで公開しているDocker環境を利用しない場合

下記に示す内容をrequirements.txtとして保存し、pipコマンド等でインストールします。

Django==4.1.4
djangorestframework==3.14.0
rest-social-auth==8.0.0
djangorestframework-simplejwt==5.2.2
django-cors-headers==3.13.0
sqlparse==0.4.3
pytz==2022.6
mysqlclient==2.1.1
uWSGI==2.0.21

それぞれのライブラリの内容・役割、インストールの要否は、以下のようになります。

ライブラリ名内容・役割インストールの要否
DjangoDjango framework必須
djangorestframeworkDjango REST framework必須
rest-social-authソーシャルログインを実行するためのライブラリ必須
djangorestframework-simplejwtJWT(JSON Web Token)形式でトークンを発行するためのライブラリ今回のケースでは必須
django-cors-headers Cross-Origin Resource Sharing(CORS) headerというものを設定し、フロントエンド側でもバックエンド側のWebAPIを実行できるようにするライブラリ今回のケースでは必須
sqlparseSQLをパースするためのライブラリ必須
pytzタイムゾーンを扱うためのライブラリ必須
mysqlclientMySQLサーバに向けてクエリを発行する際に利用するライブラリDJANGO_APP_ENV=productionの時のみ必須
uWSGIWeb Server Gateway Interface(WSGI)で通信する際に利用任意
関連ライブラリの内容・役割、インストール要否

プロジェクトの作成

新規作成時に一度だけ以下を実行します。GitHubで公開しているDocker環境を利用する場合は、すでに作成済みのため、対応不要です。

# カレントディレクトリにプロジェクトを作成する
django-admin startproject config .

アプリケーションの作成

今回は、ユーザ情報を取得するため、ユーザ情報を扱うアプリケーションを作成します。

プロジェクト作成後、一度だけ以下を実行します。GitHubで公開しているDocker環境を利用する場合は、すでに作成済みのため、対応不要です。

# manage.pyがあるディレクトリで以下を実行する
python manage.py startapp accounts

各種設定

バックエンドの設定を行う上での要となる部分です。GitHubで公開しているDocker環境を利用する場合は、すでに作成済みのため、対応不要です。

settings.pyの設定

developmentとproductionでconfigを分けるため、以下のようにディレクトリ構成を変更します。


settings/
|-- base.py
|-- development.py
|-- production.py
`-- __init__.py

上記のうち、base.pyが最も重要な部分となります。

【重要】base.pyの設定

以下のように、ライブラリの追加読み込みやアプリケーションの追加等を行います。

import os
from datetime import timedelta # SIMPLE_JWTで使用
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

# Setup
SECRET_KEY = os.getenv('DJANGO_SECRET_KEY')
DEBUG = False
ALLOWED_HOSTS = []

# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # third-party apps
    'rest_framework',            # Django REST frameworkを追加
    'rest_framework.authtoken',  # token認証のため追加
    'social_django',             # ソーシャルログインを実現するため追加
    'rest_social_auth',          # REST APIとしてソーシャルログインを実現するため追加
    'corsheaders',               # フロントエンド(React)からWebAPIを実行できるようにするため追加
    # local apps
    'accounts',                  # ユーザ情報をやり取りするため追加
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    # third-party app setting
    'corsheaders.middleware.CorsMiddleware', # CORSライブラリを利用するため追加
]

# CORSライブラリを利用するために追加
CORS_ALLOWED_ORIGINS = [
    # 今回は、React(http://localhost:3000)からのアクセスを許可するため、該当するURIを指定
    'http://localhost:{}'.format(os.getenv('FRONTEND_PORT', 3000)),
]

ROOT_URLCONF = 'config.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'config.wsgi.application'

# Password validation
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/
# 環境変数からデータを取得するように変更
LANGUAGE_CODE = os.getenv('LANGUAGE_CODE', 'en-us')

TIME_ZONE = os.getenv('TZ', 'UTC')

USE_I18N = True

USE_TZ = True

# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# User settings
AUTH_USER_MODEL = 'accounts.User' # カスタムユーザモデルを利用するため、該当するユーザモデルを指定
STATIC_URL = '/static/'  # 追加
STATIC_ROOT = '/static/' # 追加

# =====================
# REST framwork setting
# =====================
REST_FRAMEWORK = {
    # 権限に関する基本的なポリシー: 認証が必要
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
    # 認証方法: JWTによる認証
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
}
SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5), # アクセストークンの有効期限
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),   # リフレッシュトークンの有効期限
    'AUTH_HEADER_TYPES': ('JWT', ),                # 認証ヘッダーで指定する際の文字列(React側と揃える必要あり)
    'AUTH_TOKEN_CLASSES': (
        'rest_framework_simplejwt.tokens.AccessToken', # 認証時のトークンのクラス(今回は、JWTのアクセストークンを利用する)
    ),
}

# ソーシャルログインに関する設定
# Authentication backends setting
AUTHENTICATION_BACKENDS = [
    # Google OAuth2
    'social_core.backends.google.GoogleOAuth2', # 今回はGoogleアカウントで認証するため、GoogleOAuth2を指定
    # Django
    'django.contrib.auth.backends.ModelBackend',
]

# Social auth setting
SOCIAL_AUTH_PIPELINE = (
    'social_core.pipeline.social_auth.social_details',
    'social_core.pipeline.social_auth.social_uid',
    'social_core.pipeline.social_auth.auth_allowed',
    'social_core.pipeline.social_auth.social_user',
    'social_core.pipeline.user.get_username',
    'accounts.pipeline.create_user', # ユーザ生成の処理をカスタマイズしたいため追加
    'social_core.pipeline.social_auth.associate_user',
    'social_core.pipeline.social_auth.load_extra_data',
    'social_core.pipeline.user.user_details',
)

# Social OAuth setting used by social_django
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = os.getenv('DJANGO_SOCIAL_GOOGLE_OAUTH2_KEY')
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = os.getenv('DJANGO_SOCIAL_GOOGLE_OAUTH2_SECRET')
SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = [
    # Define SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE to get extra permissions from Google.
    'https://www.googleapis.com/auth/userinfo.email',
    'https://www.googleapis.com/auth/userinfo.profile',
]

また、参照先はaccounts/pipeline.pyになりますが、ユーザ生成処理に該当するパイプラインは以下のようになります。

# accounts/pipeline.py
def _generate_email(email, oauth_type, user_id):
    if not email:
        # Twitter等では、プライバシーポリシーの都合上、メールアドレスを取得できないことがあるため、疑似的なアドレスを作成した上でデータベースに登録する
        email = f'{oauth_type}{user_id}@project.dummy.address'

    return email

def create_user(strategy, details, backend, user=None, *args, **kwargs):
    if user:
        return {'is_new': False}

    fields = {
        'username': details.get('username'),
        'email':    _generate_email(details.get('email'), backend.name, kwargs.get('uid')),
        'viewname': details.get('username'),
    }

    return {
        'is_new': True,
        'user': strategy.create_user(**fields),
    }

development.pyの設定

以下に示す内容をsettings/development.pyとして保存します。

ここで、GitHubで公開しているDocker環境を利用しない場合は、sqliteのパスを環境に合わせて変更する必要があります。

import os
from .base import *

DEBUG = True
ALLOWED_HOSTS = ['*']

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join('/', 'sqlite', 'db.sqlite3'), # Docker環境を利用しない場合、適宜変更する
        'TEST': {
            'NAME': 'ut_db',
        },
    }
}

production.pyの設定

今回のケースでは利用しませんが、GitHubの内容と整合とを取るため、説明します。

以下に示す内容をsettings/production.pyとして保存します。

import os
from .base import *

ALLOWED_HOSTS = os.getenv('DJANGO_WWW_VHOST', '').split(',')

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': os.getenv('MYSQL_DATABASE'),
        'USER': os.getenv('MYSQL_USER'),
        'PASSWORD': os.getenv('MYSQL_PASSWORD'),
        'HOST': os.getenv('DB_HOST'),
        'PORT': os.getenv('DB_PORT'),
        'OPTIONS': {
            'charset': os.getenv('DB_CHARSET'),
            'collation': os.getenv('DB_COLLATION'),
        },
    }
}

manage.pyの更新

config直下に、以下に示す内容をdefine_module.pyとして保存します。

import os

def setup_default_setting():
    app_env = os.getenv('DJANGO_APP_ENV', 'development')
    setting_filename = 'production' if app_env == 'production' else 'development'
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', f'config.settings.{setting_filename}')

その後、manage.pyを以下のように変更します。

#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import sys

# === 変更箇所 ===
from config.define_module import setup_default_setting

def main():
    """Run administrative tasks."""
    setup_default_setting()

# === ここまで ====

    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)


if __name__ == '__main__':
    main()

urls.pyの設定

REST framework形式でログインするため、urls.pyを以下のように更新します。

from django.contrib import admin
from django.urls import re_path, include
from rest_framework_simplejwt.views import TokenRefreshView

urlpatterns = [
    re_path(r'^admin/', admin.site.urls),
    re_path(r'^api/login/', include('rest_social_auth.urls_token')),
    re_path(r'^api/login/', include('rest_social_auth.urls_jwt_pair')), # 今回はこちらを使用する
    re_path(r'^api/token/refresh/', TokenRefreshView.as_view()),
    re_path(r'^api/accounts/', include('accounts.urls')),
]

accountsの設定

ここでは、カスタムユーザモデルの設定例とREST framework向けの設定を行います。

私自身、REST frameworkのチュートリアルを参考に構築しているだけの状態のため、詳細は割愛します。

models.pyの設定

今回は、以下のようなカスタムユーザモデルを作成しました。

from django.db import models
from django.core.mail import send_mail
from django.contrib.auth.models import PermissionsMixin, UserManager
from django.contrib.auth.base_user import AbstractBaseUser
from django.utils import timezone
from django.contrib.auth.validators import UnicodeUsernameValidator
from django.utils.translation import gettext_lazy

class CustomUserManager(UserManager):
    use_in_migrations = True

    def _create_user(self, username, email, password, **extra_fields):
        if not username:
            raise ValueError('The given username must be set')
        if not email:
            raise ValueError('The given email must be set')
        username = self.model.normalize_username(username)
        email = self.normalize_email(email)
        user = self.model(username=username, email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)

        return user

    def create_user(self, username, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)

        return self._create_user(username, email, password,  **extra_fields)

    def create_superuser(self, username, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self._create_user(username, email, password,  **extra_fields)

class User(AbstractBaseUser, PermissionsMixin):
    username_validator = UnicodeUsernameValidator()

    username = models.CharField(
        gettext_lazy('username'),
        max_length=128,
        unique=True,
        help_text=gettext_lazy('Required. 128 characters allowing only Unicode characters, in addition to @, ., +, -, and _.'),
        validators=[username_validator],
        error_messages={
            'unique': gettext_lazy("A user with that username already exists."),
        },
    )
    viewname = models.CharField(
        gettext_lazy('view name'),
        max_length=128,
        blank=True,
        help_text=gettext_lazy('Option. 128 characters or fewer.'),
    )
    email = models.EmailField(gettext_lazy('email address'), unique=True)
    is_staff = models.BooleanField(
        gettext_lazy('staff status'),
        default=False,
        help_text=gettext_lazy('Designates whether the user can log into this admin site.'),
    )
    is_active = models.BooleanField(
        gettext_lazy('active'),
        default=True,
        help_text=gettext_lazy(
            'Designates whether this user should be treated as active. Unselect this instead of deleting accounts.'
        ),
    )
    date_joined = models.DateTimeField(gettext_lazy('date joined'), default=timezone.now)

    objects = CustomUserManager()

    EMAIL_FIELD = 'email'
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    class Meta:
        verbose_name = gettext_lazy('user')
        verbose_name_plural = gettext_lazy('users')

    def __str__(self):
        return self.__unicode__()

    def __unicode__(self):
        return self.viewname or self.username

    def get_full_name(self):
        return str(self)

    def get_short_name(self):
        return self.get_full_name()

    def email_user(self, subject, message, from_email=None, **kwargs):
        send_mail(subject, message, from_email, [self.email], **kwargs)

serializers.pyの設定

カスタムユーザモデルの内容に合わせて、以下のように返却するデータを定義します。

from django.contrib.auth import password_validation
from rest_framework import serializers
from django.contrib.auth import get_user_model

User = get_user_model()

class UserListSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        # レスポンスに含めるデータ:ユーザ名、メールアドレス、表示名
        fields = ['username', 'email', 'viewname']

views.pyの設定

REST frameworkにより提供される機能をフル活用してviewを設定します。

from rest_framework import viewsets
from django.contrib.auth import get_user_model
from .serializers import UserListSerializer

User = get_user_model()

class UserViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = User.objects.filter(is_staff=False, is_active=True)
    serializer_class = UserListSerializer

urls.pyの設定

REST frameworkのDefaultRouterを利用してルーティングの設定を行います。

from django.urls import include, re_path
from rest_framework.routers import DefaultRouter
from . import views

router = DefaultRouter()
router.register(r'users', views.UserViewSet, basename='user')

app_name = 'accounts'

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

データベースのマイグレーションとサーバの起動

最後にデータベースのマイグレーションを行った後、サーバを起動します。

サーバの起動に関しても、GitHubで公開しているDocker環境を利用する場合と利用しない場合で進め方が異なるため、それぞれ分けて説明します。

GitHubで公開しているDocker環境を利用する場合

まず、以下のコマンドを実行し、実行時ユーザのUIDGIDを確認します。

id ${USER}
uid=1000(yuruto) gid=1000(yuruto) groups=1000(yuruto)

調べた結果をdocker-compose.ymlPUIDPGIDに反映します。

今回の場合、UID=1000GID=1000となるため、以下のように設定します。

    environment:
      # PUID = 1000 (= uid), PGID = 1000 (= gid)を設定する
      - PUID=1000
      - PGID=1000

そして、下記のコマンドを実行します。この時、ReactとMySQLもコンテナとして起動されます。

./wrapper.sh start

GitHubで公開しているDocker環境を利用しない場合

下記のコマンドを実行します。最初は、データベースの構築が必要になるため、多少時間がかかります。

python manage.py makemigrations
python manage.py migrate
python manage.py runserver 0.0.0.0:8000

エラー無くサーバが立ち上がれば成功です。

まとめ

今回は、Django REST frameworkを用いたバックエンド側の設定内容について説明しました。

対象となるライブラリのインストールとその設定情報の情報のみのため、理解が十分追い付かないかもしれません。

次回、フロントエンド側の処理を記載するため、その際の使われ方と併せて確認することで、どのような呼び出し関係になるかを把握いただければと思います。

あわせて読みたい
【解説】Social OAuthによるアプリケーション連携(3/3)【Django REST framework】

続きを見る

スポンサードリンク

-プログラミング
-, , ,