LoginSignup
10
8

More than 5 years have passed since last update.

Django×PinaxでWebサービス入門②|ローカルでアプリを動かす

Last updated at Posted at 2018-06-03

この記事の内容

この記事では、Django製のWebアプリケーションを作り、自分のローカルPCでブラウザからつないで見るところまで進めます。
(ずっとターミナルでコマンドを打ち込み、いろいろインストールしたり何かを自動で構築したりということが進みます)

全体像で見てみると、この緑色で囲った部分が対象です。

Overall Structure_01.png

ターミナルとは

ターミナルはMacで標準搭載されている、コンピューターに直接命令(コマンド)をうちこむアプリです。黒い画面(デフォルトは白ですが)にひたすら文字が流れていくあれです。
Finderで アプリケーション > ユーティリティ > ターミナル から起動できます。

  • Homebrewのインストール
  • Python3のインストール
  • Virtualenvで仮想環境を作る
  • Django(Pinax)を使ってWebアプリケーションを構築
  • npmでフロント周りの静的ファイルを生成

ということをやっていきます。

Homebrewのインストール

後ほどPython3をインストールするのですが、そのためにHomebrewというMacOS用のパッケージマネージャーが必要になるので、それを先にインストールします。コマンドは公式サイト通りです。

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

ターミナルにコマンドをコピペするとき

上記のようなコマンドをターミナルに貼り付けて実行するということが頻繁に起きます。
その時に#もしくは$という文字のあとにコマンドが書かれていても、そられは除いてコピペしてください。これは管理者ユーザー(rootユーザー)でログインしているか一般ユーザーログインしているかを表すために慣例的に記載しているものです。
(参考)【完全初心者向け】Linuxのrootユーザとは?

パッケージマネージャーとは
何かを作るときは、いろいろなパッケージ(ライブラリ)を駆使しながら進めていきます。その時にそれらパッケージ(ライブラリ)を簡単にインストール・アップデート・アンインストールできるようにする管理ツールが必要になってきて、このことをパッケージマネージャー(パッケージ管理)と呼びます。
Homebrewの他にも、Pythony用パッケージマネージャーのpip、CentOSで使うyumなど様々なものがあります。

Python3のインストール

Pythonのバージョンは2系と3系で構文の書き方が違ったり利用できるライブラリが異なったりします。そのため目的に応じてPythonのバージョンを使い分けられる必要がででき、アプローチとしては、

  • 元々macに入っている2系に加えて3系をインストールして、別々のコマンドで使い分けるという方法 (今回はこちらで説明します。)
  • pyenvという複数バージョンのPythonを簡単に切り替えることができるライブラリを用いる方法

があります。

MacにはPython2系が予めインストールされています。それを確認してみましょう。

$ python -V

Python 2.7.10

どこにインストールされているかも見てみます。

$ which python

/usr/bin/python

それでは、Python3系をHomebrewでインストールします。

$ brew install python3

これで最新版のPython3が入ります。バージョンとインストール先を確認します。

$ python3 -V

Python 3.6.5

$ which python3

/usr/local/bin/python3

Virtualenvで仮想環境を作る

続いて、VirtualenvというPythonの仮想的な環境を作るためのパッケージを使って、今回作成するTODOアプリ専用の環境を作成します。
例えば2つのPython製アプリケーションを開発している場合に、一方は特に制約なく最新バージョンのPythonを利用できる、しかしもう片方は最新バージョンのPythonに対応していないライブラリを利用しないといけない、といったことがあります。
こういった場合に、Pythonのバージョンやインストールしたライブラリ群が異なる環境をわけて作ることで、2つのアプリを共存させられるようになります。

まず、VirtualenvをpipというPython用のパッケージマネージャーを使ってインストールします。

$ pip install virtualenv

そして、これから作成してくTODOアプリのための作業ディレクトリを作成します。

$ mkdir todo

作成したディレクトリに移動します。

$ cd todo

virtualenvのコマンドで先ほどインストールしたPython3を指定して環境を作成します。
はじめにhomebrewでPython3をインストールした際にコマンドのパスが通ったので、そのコマンドを利用してPythonのバージョンを指定します。

$ virtualenv -p python3 todo_env

これでtodo_envという名前のTODOアプリ専用の仮想環境ができました。これを起動します。

$ source todo_env/bin/activate

ターミナルでユーザー名の頭に(todo_env)というものが付いたと思います。これが仮想環境の中にいるということを意味しています。
それでは、さっきと同様にPythonのバージョンを確認してみます。

$ python -V

Python 3.6.5

さきほどインストールしたPython3系が利用されています。

ここまでで何を作ったのかは下図のような感じです。

00.png

MacOSにはPython2とPython3を別々にインストールし、それぞれpythonpython3というコマンドで呼び出せるようにしました。そしてtodo_envという仮想環境を作るときに、Python3の方を利用するように指定しました。
なので図のようにこの他にも仮想環境を作り、適したバージョンのPythonを適用することができます。

なお、この仮想環境を終了する場合はdeactivateコマンドを使います。

$ deactivate

Django(Pinax)を使ってWebアプリケーションを構築

ようやくDjangoを使ってWebアプリケーションを作っていきます。ここでDjangoとPinaxに関して軽く触れます。

Django

DjangoはPython製のWebフレームワークです。2005年にリリースされたもので結構歴史が長く、Python製Webフレームワークの中ではかなり有名です。
The Top Web Development Frameworks in 2018 によると、

  1. Djangoは早い開発スピードを実現する
  2. Djangoはセキュリティ面に優れている
  3. Djangoはスケーラブルで、トラフィックの増加に対応しやすい
  4. Djangoは全ての機能が搭載されている

と書かれています。デフォルトの機能、また様々なDjango用のライブラリが豊富だったりDjangoプロジェクトがあるため、こんなことをやりたいというときにはかなりサクサク要望を実現できます。
例えば『スマホアプリでも利用できるようにしたいのでAPIを作りたい』といったものや、『Q&Aページを作ってユーザーの問い合わせを効率的に管理したい』といったものなど探すと結構出てきます。

Webフレームワークとは

Webアプリケーションを作るときには、クライアント(普段使うPCとかスマホ)からリクエスト(このページを見せて)を受け、それに応じてデータベースを呼び出して情報を取る機能や、データベースにどんな情報を蓄積するか管理する機能、さらにレスポンス(HTML)を作ってクライアントに返す機能などが求められます。Webフレームワークとはこれらの機能を用意しておいて、Webアプリケーションを開発しやすくしたものです。

Pinax

Pinaxは有志が作っているDjango製のアプリケーションの雛形で、Webでよく使われる機能があらかじめ含まれたプロジェクトです。これを使ってDjangoのWebアプリケーション開発を始めることで、かなり効率的に進められるようになります。

Pinax本家サイト(英語)

ものを見たほうが早いので、実際に使っていきます。

まず、Pinaxのコマンドラインインターフェイスをpipでインストールします。

$ pip install pinax-cli

これでpinaxのプロジェクトを利用する準備ができました。どんなプロジェクトがあるか見ていきます。

$ pinax projects

Release Project
------- ---------------
  4.0.4 account
  4.0.4 blog
  2.0.4 company
        documents
        social-auth
  4.0.4 static
  4.0.4 stripe
        team-wiki
  3.0.4 waitinglist
        wiki
  4.0.4 zero

利用可能なプロジェクトの一覧が表示されています。ここで言うプロジェクトの実のところは、作りたいWebアプリケーションごとに必要な機能が用意されたDjangoプロジェクトです。いくつか見ていくと、

  • account : 会員管理系のサイト用プロジェクトです。会員登録・ログイン・ログアウト・退会といった機能があります。
  • wiki : wikiサイト用のプロジェクトです。権限を受けたユーザーがwikiページを投稿できるといった機能があります。
  • stripe : 課金サービス系のサイト用プロエクとです。決済サービスのstripeと連携する機能があります。

などがあります。もっと詳しくは Pinax Starter Projects を御覧ください。

今回はオーソドックスなaccountを利用します。アプリケーションの名前はtodoとします。

$ pinax start account todo

TODOアプリのプロジェクトが生成されたので、ディレクトリの中に入ります。

$ cd todo

このプロジェクトを動かすためのライブラリを今の仮想環境にインストールします。インストールが必要なライブラリはこのディレクトリの中にあるrequirements.txtというファイルに定義されています。

$ pip install -r requirements.txt

どんなものがインストールされたのか見てみます。

$ pip list

Package               Version  
--------------------- ---------
certifi               2018.4.16
chardet               3.0.4    
click                 6.7      
colorama              0.3.9    
crayons               0.1.2    
Django                2.0.6    
django-appconf        1.0.2    
django-bootstrap-form 3.4      
django-user-accounts  2.0.3    
idna                  2.6      
jsonfield             2.0.2    
pinax-cli             1.1.4    
pinax-eventlog        2.0.3    
pinax-templates       2.0.1    
pinax-webanalytics    4.0.2    
pip                   10.0.1   
pytz                  2018.4   
requests              2.18.4   
setuptools            39.2.0   
urllib3               1.22     
wheel                 0.31.1 

Djangoやユーザー管理用のdjango-user-accountsがインストールされているのがわかります。

次に、このアプリケーションで使うデータベースのテーブルを作ります。
なお、ここからmanage.pyというファイルを経由してコマンドを実行していきます。これらは全てDjangoが用意しているコマンドです。

$ python manage.py migrate

Operations to perform:
  Apply all migrations: account, admin, auth, contenttypes, eventlog, sessions, sites
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying account.0001_initial... OK
  Applying account.0002_fix_str... OK
  Applying account.0003_passwordexpiry_passwordhistory... OK
  Applying account.0004_auto_20170416_1821... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying eventlog.0001_initial... OK
  Applying eventlog.0002_auto_20150113_1450... OK
  Applying eventlog.0003_auto_20160111_0208... OK
  Applying sessions.0001_initial... OK
  Applying sites.0001_initial... OK
  Applying sites.0002_alter_domain_unique... OK

ここで行ったのは『マイグレーション』という処理です。DjangoにはModelというデータベースの定義を『マイグレーションファイル』として作成して、それのファイルをもとにその定義のテーブルを作るという機構があります。
なのでここではaccountプロジェクトで定義されていたファイルを読み込んで、テーブルが生成されました。

今はまだテーブルにデータが入っていない状態ですが、次のコマンドで最低限のサイト情報を取り込みます。

$ python manage.py loaddata sites

fixtures/sites.jsonの定義を基にデータをロードする処理が行われ、データが作られました。

今作られたデータを見てみたいので、管理画面にログインするために管理者用のアカウントを作ります。これもDjangoに予め用意されている機能が利用できます。
ここでは任意のUsernameEmail addressPasswordを入力します。
今回はUsernameuserとし、Email addressは必須ではないので未入力で進めます。

$ python manage.py createsuperuser

Username (leave blank to use 'user'): user
Email address: 
Password: 
Password (again): 
Superuser created successfully.

パスワードは表示されません

ここではPasswordはキーを入力しても何も表示されませんが、セキュリティに配慮してなので実際は入力できています。

サーバーを起動します。
Djangoには開発用のサーバーが用意されているので、わざわざApacheなどWebサーバーを立てなくても動作の確認ができます。

$ python manage.py runserver

Performing system checks...

System check identified no issues (0 silenced).
June 03, 2018 - 07:20:28
Django version 2.0.6, using settings 'todo.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

サーバーが起動されました。ブラウザからhttp://localhost:8000/admin/login/?next=/admin/にアクセスしてみます。

Log in I Django site admin - http___localhost_8000_admin_login__next=_admin_.png

管理画面にアクセスできました。この管理画面はDjangoの特徴の一つで、データベースに接続しなくてもブラウザからデータの閲覧・作成・編集・削除ができるものです。
実際に処理が反映されたかどうか、データベースを見に行くみたいな手間が省けてかなり良いです。

先程登録したuserとパスワードでログインすると、このアプリケーションで管理している情報を見ることができます。一番下にあるSitesというリンクからhttp://localhost:8000/admin/sites/site/にアクセスすると、サイトのレコードが2つ登録されてるのがわかると思います。これが先程loaddataコマンドで作成したデータです。

Select site to change I Django site_ - http___localhost_8000_admin_sites_site_.png

なお、runserverコマンドを叩いたときにhttp://127.0.0.1:8000/でサイトが見れますというふうに言われるのですが、このタイミングだとlocalhostしか受け付けない設定になっているのと、CSSやjsなどフロント周りの静的ファイルを生成していないのでhttp://localhost:8000/にアクセスしても見た目がくずれている状態です。

一旦Ctrl+Cでサーバーを停止して次に進みます。

※もし違うコマンド(Ctrl+Z)やターミナル自体を閉じてしまうと、サーバーは起動したままになります。そんなときはlsofコマンドでポート番号からプロセスを探して、killコマンドでプロセスを終了できます。

$ lsof -i :8000

COMMAND     PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
python3.6 12685 user    6u  IPv4 0x581221ac75463bd3      0t0  TCP localhost:irdmi (LISTEN)

$ kill -9 12685

npmでフロント周りの静的ファイルを生成

ということで、最後にフロントまわりの静的ファイルを生成します。
PinaxではCSSやjsなどのファイルを管理するためにnpmという技術を利用しているので、npmを使って静的ファイルを生成するところまで進めます。流れとしては、

  1. nodebrew(nodeのバージョン管理ツール)をインストール
  2. Node.jsとnpm(Node.js製のパッケージマネージャー)をインストール

です。またバージョンとかパッケージマネージャーとかが出てきて辟易とするかもしれませんが、一度入れてしまえば便利な技術です。
先程はPython2とPython3を別々に入れたのでしっかりと扱いませんでしたが、nodeのバージョン管理ツールであるnodebrewのように、Pythonのバージョン管理ツールであるpyenvというものもあります。

では一番最初にインストールしてMacOS全体のパッケージマネージャーであるHomebrewを利用して、nodebrewをインストールします。

$ brew install nodebrew

nodebrewのバージョンを見てみます。

$ nodebrew -v
nodebrew 1.0.0

そして、setupコマンドで設定周りの指示を受けます。

$ nodebrew setup

Fetching nodebrew...
Installed nodebrew in $HOME/.nodebrew

========================================
Export a path to nodebrew:

export PATH=$HOME/.nodebrew/current/bin:$PATH
========================================

パスを通すように書いてあるので、上記で表示されたコマンドを実行します。

$ export PATH=$HOME/.nodebrew/current/bin:$PATH

nodebrewは複数バージョンのNode.jsを管理するので、インストール→どれを利用するか指定するという流れになります。今回はv9.3.0を使います。
(安定版のv10.3.0を試しましたが、pinaxが対応していないようでした。)

$ nodebrew install-binary 9.3.0

インストールされたバージョンを見てみます。

$ nodebrew list

v9.3.0

current: none

まだcurrent: noneなので、どのバージョンも指定されていません。今インストールしたバージョンを指定します。

$ nodebrew use 9.3.0

use v9.3.0

すると、node.jsとnpmが使えるようになります。

$ node -v

v9.3.0

$ npm -v

5.5.1

ようやくWebアプリケーションの方に戻ることができます。最初に今いる同一階層にあるpackage.jsonというファイルの定義に従って必要なパッケージをインストールします。

$ npm install

続いて、Pinaxで用意されているcssファイルとjsファイルを生成します。

$ npm run dev

すると、static/dist/配下に静的ファイルが生成され、先程シャットダウンした開発用サーバーが起動しました。
ここでhttp://localhost:8000/にアクセスすると、見た目がちゃんとしたトップページが表示されます。

example.com [localhost] I pinax-project-account - http___localhost_8000_.png

Bootstrap4を使っていて、整っています。
会員登録やログイン・ログアウト、登録情報の変更、退会などもできるので試してみてください。

ちなみに、このnpmの定義ファイルpackage.jsonは大まかにnpmでどのようなライブラリを管理するか、そしてどのようなscriptの処理を持つかを司っています。このscriptの部分を見ると、下記のようになっています。

"scripts": {
    "clean": "rm -rf static/dist && mkdir -p static/dist/js && mkdir -p static/dist/css && mkdir -p static/dist/images",
    "build:js": "browserify -t [ babelify --presets [ env ] ] -t envify -o static/dist/js/site.js static/src/js/index.js",
    "build:css": "node-sass static/src/scss/index.scss static/dist/css/app.css",
    "copy:images": "cp -r static/src/images/* static/dist/images/ 2>/dev/null || :",
    "optimize:js": "uglifyjs static/dist/js/site.js -m -c warnings=false -o static/dist/js/site.js",
    "optimize:css": "cssnano static/dist/css/app.css static/dist/css/app.css",
    "optimize": "npm run optimize:js && npm run optimize:css",
    "watch:test": "onchange static/src/js/**/*.js -- npm run test",
    "watch:lint": "onchange static/src/js/**/*.js -- npm run lint",
    "watch:js": "watchify -t [ babelify --presets [ env ] ] -t envify static/src/js/index.js -o 'exorcist static/dist/js/site.js.map > static/dist/js/site.js' -dv",
    "watch:css": "node-sass static/src/scss/index.scss static/dist/css/app.css --watch -r",
    "build": "npm run clean && concurrently \"npm run build:js\" \"npm run build:css\" \"npm run copy:images\" && npm run optimize",
    "watch": "npm run clean && npm run copy:images && npm run build:css && concurrently --raw \"npm run watch:lint\" \"npm run watch:js\" \"npm run watch:css\"",
    "dev:browser-sync": "browser-sync start --no-open --proxy localhost:8000 --files \"static/dist/js/*.js, static/dist/css/*.css\"",
    "dev": "concurrently --raw \"./manage.py runserver\" \"npm run watch\" \"npm run dev:browser-sync\"",
    "lint": "eslint static/src/**/**/*.js",
    "test": "mocha --recursive --compilers js:babel-register static/src/tests/index.js",
    "compile": "NODE_ENV=production npm run clean && concurrently \"npm run copy:images\" \"npm run build:js\" \"npm run build:css\"",
    "heroku-postbuild": "npm run compile && npm run optimize"
},

この中にある dev というのが、npm run devというコマンドを叩いたものです。これを見ると、

  • manage.py runserver : Webサーバーを起動してアプリケーションにローカルでアクセスできるようにする(先程叩いたコマンドです。)
  • npm run watch : scssファイルに変更があったときに、変更を検知してcssファイルを更新する。
  • npm run dev:browser-sync : 静的ファイルが更新されると、ブラウザをリロードする

という3つのコマンドが内包されているのがわかります。
このあとでIDE(統合開発環境)であるPyCharmを使っていきますが、その時はnpm run watchを、またVPSにデプロイしたあともWebアプリケーションを動かすのはApacheの役割でmanage.py runserverは必要ありません。そのためVPS上でもnpm run watchのみを使うことになります。

次回

とまあコードを一行も書いていませんが、何やらできあがりました。
次回はPython用統合開発環境(IDE)であるPyCharmをセットアップし、Django製Webアプリケーションの開発を効率的に行うための土台を作ります。

Django×PinaxでWebサービス入門③|PyCharmをセットアップ

10
8
2

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
10
8