Laravel使いがDjangoでwebアプリを作るよその1:アプリの概要と環境構築
技術スタック DjangoPythonLaravelPHP

Laravel使いがDjangoでwebアプリを作るよその1:アプリの概要と環境構築

2022.02.12

こんにちはjunです。最近Laravelでシステムを作る機会が何回かあったので、Laravelによる構築がかなり得意になってきました。しかし会社の方で「pythonを使用した機械学習や統計の機能をwebアプリとして使用できるアプリを開発したい」という企画がでてきました。

pythonで機械学習や統計の処理(モデル)を作成し、UIやロジックの部分をwebフレームワークで作成します。できたらwebフレームワークの処理部分にて統計ロジックをimportして、データの引き渡しを行いたいと思いました。しかしLaravelはPHPなので連携が難しいです。

そのため「Python製のwebフレームワークであるdjangoを利用できないか?」と思い、Djangoの勉強をスタートしました。チュートリアルはひとまず終えましたが、Laravelをやっていたおかげで

  • どんな機能があると便利か?
  • Laravelのこの機能がDjangoのこの記述にあたるのか?
  • 実務上必要となるこの機能を実装するには何を使えばいいのか?

という視点を用いて学習することができました。このシリーズでは「Laravelを使っていたPHP開発者がDjangoとPythonを使用してアプリを作る」ことを通じてDjangoの学習をしたいと思っています。記事内ではDjangoにおける実装とLaravelにおける実装をリンクしながら解説していきたいと思います。

利用するDjangoのバージョンは3.2で、Laravelは8とします。第1回のこの記事は環境構築とアプリの概要、Djangoの開発コンセプトやディレクトリ説明がメインとなります。

なおシリーズでは以下の内容を押さえていることを前提としています

  • Laravelの実務開発経験があるまたは、完成したアプリを作ったことがある。
  • Laravelのコンセプトやディレクトリ構成を知っている。
  • PythonがPCにインストールされ、基本的な記述を理解している。
  • PHPを触ったことが多いが、Pythonはそれほどない。
  • Djangoのチュートリアルは行っており、必須の内容は知っている。
  • MVCの概念を知っている、使える。

それでは早速始めていきましょう。

参考資料

環境構築

今回の環境構築はdockerを用いて作成しようと思います。適当なディレクトリ を作成し、docker-compose.yamlとビルドファイルを作成します。

mkdir laravel_django
cd laravel_django

touch Dockerfile
touch docker-compose.yaml
mkdir source

まずはDockerfileでDjangoが稼働するpythonの環境を作成します。なお、この環境ではApacheやnginxといったwebサーバーとpythonとの連携設定は行わないものとします。コンテナ内でrun serveを行います。

Dockerfile

Dockerfileを以下の様に記述します。

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/

python3 イメージをもとにpythonが動く環境を用意します。

docker-compose

docker-compose.yamlは以下の様に記述します。

docker-compose.yaml
version: '3'

services:
  db:
    image: mysql:5.7
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    environment:
      MYSQL_DATABASE: preform
      MYSQL_USER: test
      MYSQL_PASSWORD: testtest
      MYSQL_ROOT_PASSWORD: rootroot
      TZ: Asia/Tokyo
    ports: 
      - "3306:3306"
    volumes: 
      - djangodemo:/var/lib/mysql
  phpmyadmin:
    image: phpmyadmin
    ports:
      - "8080:80"
    environment:
     - PMA_ARBITRARY=1
     - PMA_HOST=db:3306
     - PMA_USER=root
     - PMA_PASSWORD=rootroot
  web:
    build: .
    command: python3 manage.py runserver 0.0.0.0:8000
    volumes:
      - ./source:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
volumes: 
  djangodemo: {}

dbではデータベースを定義しています。DjangoはSQLiteを使用した簡易的なDBが用意されています。ただし実務ではmysqlなどのDBサーバーを使用することが多いので、今回はmysqlを使用できる様にします。

Djangoでmysqlを使用するためにはpythonモジュールのmysqlclientが必要です。この環境にはデフォルトでないので注意してください。他のDBサーバーを使用する場合は適宜ドライバをインストールしてください。 本家ドキュメントを参照

DB内部をすぐに確認できる様にphpmyadminを入れておきます。(好みなのでなくてもいいです。) そしてwebでは同階層にあるDockerfileをビルドして実行できる様になります。立ち上げ時にpython3 manage.py runserver 0.0.0.0:8000をしてwebサーバを立ち上げる設定にしています。

このコンテナを起動する前に requirements.txt をDockerfileと同じ階層に生成しておき、以下の内容を記述します。

requirements.txt
Django==3.2
mysqlclient==2.1.0

requirements.txt はpythonライブラリ管理ツールpipの設定ファイルです。npmのpackage.jsonやcomposerのcomposer.jsonといったものと同じです。pythonのモジュール管理はpipを使用することが多く、requirements.txt は環境ないの依存するモジュールとそのバージョンを記述して配置しておきます。そしてrequirements.txt がある階層で pip installをすることで自動的に依存関係をインストールしてくれます。Django3.2とmysqlclientを記述しておきます。

requirements.txtを記述したら以下のコマンドを実行してDjangoのソースを作成します。

docker-compose run web django-admin.py startproject djangodemo .

するとsource/配下にDjangoのソースが生成されるはずです。 そして準備が整ったらdocker-compose up -d --build を行って構築を行います。問題なくいった場合はブラウザにて localhost:8000 を閲覧すると、Djangoのウェルカムページが表示されるはずです。

アプリ概要

今回作成するアプリはn○teみたいなブログサービスを作成しようと思います。

ユーザー系の特徴

  • 利用する際にはユーザーとしてアカウントを作る(今回は全てゲストとする)。
  • ログインはアドレスとパスワードを使用する。
  • アプリを利用する一般ユーザーと管理を行う管理ユーザーが存在する。
  • 管理ユーザーは特定の管理用ルートから入る。
  • 退会可能。退会時は関連するデータは削除される。
  • プロフィールでは以下の項目を持つ
    • ユーザー名(仮名)
    • プロフィール文
    • アバター写真

ブログ機能

  • ブログを作成することができ、公開することができる。
  • ブログは以下の項目を持つ
    • タイトル
    • 内容(リッチテキスト)
    • タグ(任意)
    • 公開日時
  • 下書きとして保存することができる。更新時も下書き可能。
  • 任意数のタグを添付できる。タグはユーザーが新しく作成できる。
  • 削除可能
  • 画像の添付が可能。
  • アップロードした画像は管理できる。
  • 公開側からコメント可能

一覧検索機能

  • サイトトップは投稿された記事が新着順に並ぶ。
  • 任意のタグを選んで一覧表示することが可能。
  • 部分一致検索も一応可能とする。

一通りユーザーエンティティから、記事のCURD、リレーションの練習はできると思います。すべてのビューはpython側でレンダリングを行い、Vue.jsなどは今回使用しません。違う機会にrest apiを使用した構成を作ってみたいとおおいます。

デザインに関してはいつものbootstrapを使用します。

Djangoの大まかな解説

詳細なロジックなどは次の記事で解説したいと思います。今回はDjangoのディレクトリ構成やLaravelと似ているとこやリンクしている中核的な機能を解説したいと思います。

コマンドによる制御

Laravelでは php artisan を使用することでコントローラーを作ったり、マイグレーションを実行したりできます。Djangoにも似た様なものがあります。使用する時はソーストップの manage.py がある箇所で実行します。例えば以下の様な機能があります。

# 簡易webサーバーを起動
python3 manage.py runserve

# マイグレーションを実行
python3 manage.py migrate

# アプリのテンプレートを作成
python3 manage.py startapp APP_NAME

Laravelで例えると

# 簡易webサーバーを起動
php artisan serve

# マイグレーションを実行
php artisan migrate

# コントローラーのテンプレートを作成
php artisan make:controller CONTROLLER_NAME

以上の様になります。この python3 manage.pyで実行できる内容はこちらのドキュメントで知ることができます。

ディレクトリとファイルの構成

初期のファイル構成は以下の様になっています。

├── db.sqlite3
├── djangodemo
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py

djangodemo/ はDjangoのアプリを最初に作成した時に生成されるディレクトリです。djangodemo/ では特に settings.pyurls.pyが重要です。

設定ファイル

settings.py はLaravelでいうconfig/ディレクトリ配下のファイルたちを一つにまとめた様なものになっています。特にconfig/app.phpの記述が近いかもしれません。一部抜粋して解説します。

settings.py
BASE_DIR = Path(__file__).resolve().parent.parent

SECRET_KEY = 'hogehoge'

# SECURITY WARNING: don't run with debug turned on in production!
# Laravelのapp.debugと同じ
DEBUG = True

# Application definition
# Djangoが利用可能なアプリ(モジュール)Laravelにはないかも。
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

# laravel の app/Http/Kernel.php のmiddlewareみたいなもの
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',
]

# Laravelのroutesみたいなもの。
ROOT_URLCONF = 'djangodemo.urls'

# Laravelのビューテンプレートが resource/viewであることを決めている様なことと同じ。DjangoないのTemplateの読み込み先を定義している
TEMPLATES = [
    # ...
]

WSGI_APPLICATION = 'djangodemo.wsgi.application'

# Laravelのconfig/database.phpと同じ。使用するDBドライバやアクセス情報を記述。
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'preform',
        'USER': 'root',
        'PASSWORD': 'rootroot',
        'HOST': 'db',
        'PORT': '3306',
    }
}

# 静的ファイルを配置する箇所。Laravelのstorageディレクトリ を定義している様なもの。
STATIC_URL = '/static/'

ルーティング

次はurls.pyです。これはLaravelでいうところの routes/と内容的には一緒です。ここでHTTPリクエストに対する処理を結びつけています。Urlディスパッチャと言われています。Laravelではweb.phpapi.phpなどいくらか分かれていますが、Djangoではデフォルトで一つです。詳細な記述は次回説明します。

アプリ側のディレクトリ

次にアプリを作成します。Djangoは機能ごとにディレクトリを分割しアプリ(app)と呼んでいます。例としてユーザーのアカウント設定や認証を行う機能を作成するために、accountというアプリを作成します。

python3 manage.py startapp account

ディレクトリ が一つ増えて、account/というのが作成されたはずです。アプリ内には初期では以下の通りテンプレートが作成されます。

├── account
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── db.sqlite3
├── djangodemo
├── manage.py

Laravelはapp/配下にコントローラーやモデル、ジョブなどのクラスファイルを定義します。独立した機能であってもapp/配下に配置してクラス名などで判別する感じです。

しかしDjangoは機能ごとにディレクトリ を作成し、その機能に関連するモデル、ビュー、テストの設定を記述します。ここがLaravelとすこし違うところです。

アプリをsetting.pyINSTALLED_APPSに記述することで、

from account.model import Account

# account/model.py のAccountクラスを使用する

などそのアプリ内機能をモジュールとして使用できます。Laravel(PHP)風に解説すると、適切な名前空間を定義して任意のファイルでuseする感じです。

use App\Models\Account

それぞれのファイルを説明します。

  • admin.py:Djangoが提供する管理者画面でモデルの内容をどう表記するかを定義します。
  • apps.py:アプリの設定ファイル。アプリの名前やデフォルトのプライマリーキーなどを設定でき、INSTALLED_APPSに必要
  • models.py: アプリのモデルファイル。テーブルや使用するフィールドの定義などを行う。Laravelでいうapp/models
  • tets.py: アプリのテストファイル。テストコードを記述する。Laravelでいうtests/
  • views.py: アプリのビューファイル。DjangoではビューはLaravelでいうControllerみたいな働きをする。
  • migrations/: DBに対する変更、マイグレーションファイルが格納されます。Laravelでいう、database/migrationsです。

のこっている __init__.pyですがこれはpythonがディレクトリ をパッケージとして認識して、importできる様にするために必要なファイルです。python2ではこのファイルがないとimportが動作しません。python3からは不要ですが、後方互換性のために作っておいて損はありません。

from account.models
"""
accountディレクトリ(パッケージ)のmodels.py(モジュール)を読み込むということが,
__init__.pyがあるとできる。
"""

今回はとりあえずここまで

ひとまずこの回ではディレクトリやファイルの説明までとしておきます。次回はユーザーモデルを使用した認証の実装とLaravelと比較したCRUDの一部(記事の作成)を実装します。

コメント

コメント読み込み中..

Copyright © 2021 jun. All rights reserved.