Python Djangoフレームワークを使ってみる

## はじめに

この記事は ウェブクルー Advent Calendar 2018 の24日目の記事です。
昨日は @kalzit さんの「AWS Toolkits for IntelliJ による Lambda 開発フローを試してみる」でした。

## 概要

PythonのDjangoフレームワークを使ってみたかったので、諸々のインストールからアプリ開発を進めるまでのセットアップ等を試してまとめてみたいと思います。

## 環境

* Windows 10
* Python 3.7.1
* Django 2.1.3

## 環境準備

### Pythonのインストール

[Python](https://www.python.org/downloads/)のダウンロードおよびインストールをします。

![python3-7-1-install.png](https://qiita-image-store.s3.amazonaws.com/0/314263/462cb83e-eaff-1c2e-0b01-8ff0176c2f40.png)

Install Nowをクリックする前に、「Add Python 3.7 to PATH」にチェックを付けます。
このチェックにより、環境変数のPATH設定を個別で行う必要が無くなります。

### virtualenvのインストール

Pythonの仮想環境を作るツールをインストールします。
Pythonのバージョンや使用するパッケージを固定した仮想環境を構築することができるようになります。

```
C:\Users\username> pip install virtualenv
```

### Djangoのインストール

今回、仮想環境でインストールを行っていきます。
そのため、まずは以下のコマンドで仮想環境を作ります。

```
C:\Users\username\workspace> virtualenv env-test
```

※作業ディレクトリは任意の場所で構いません。

env-testという仮想環境の構築ができたので、仮想環境に入ります。

```
C:\Users\username\workspace> cd env-test
C:\Users\username\workspace\env-test> Scripts\activate
(env-test) C:\Users\username\workspace\env-test>
```

仮想環境に入ると、(env-test)のように、作成した仮想環境の名前が表示されるようになります。

仮想環境に入ることができたので、Djangoをインストールしていきます。

```
(env-test) C:\Users\username\workspace\env-test> pip install django==2.1.3
```

上記の実行で

```
Successfully installed Django-2.1.3 pytz-2018.7
```

のような表示がされれば成功です。

## Djangoプロジェクトの作成

仮想環境に入った状態で、プロジェクトを作成したい任意のディレクトリに移動します。
ディレクトリ移動したら、startprojectでプロジェクトの作成ができます。

```
(env-test) C:\Users\username\workspace\env-test> cd C:\Users\username\django
(env-test) C:\Users\username\django> django-admin.py startproject django_test
```

上記を実行すると、django_testというフォルダの中に、以下のようなディレクトリ構成が作られます。

![init-django-project.png](https://qiita-image-store.s3.amazonaws.com/0/314263/b067e9d2-9def-8e1c-409f-bdfb23376b75.png)

この後は実際に、このベースを用いて、Webアプリの設定や開発を行っていくわけですが、
ひとまずはローカルで動作させることができるのかの確認をしてみます。
作成したdjango_testの中に移動してrunserverします。

```
(env-test) C:\Users\username\django> cd django_test
(env-test) C:\Users\username\django\django_test> python manage.py runserver
```

上記のコマンドを実行後に、ブラウザで確認してみると以下のような表示がされれば、ひとまずは成功です。

![django-runserver.png](https://qiita-image-store.s3.amazonaws.com/0/314263/b974a698-ca18-4c16-96d6-ed5eadfdf3ee.png)

また、ポートを指定したい場合は、以下のように実行します。

```
(env-test) C:\Users\username\django\django_test> python manage.py runserver 8080
```

## DjangoでWebアプリ開発
これまでの作業で、Pythonのインストールから、仮想環境でDjangoフレームワークのインストール
および新規プロジェクトでローカルサーバーでの実行確認まで行うことができました。

ここからは、実際に簡単なアプリの設定や画面遷移等の実装を試してみようと思います。

### タイムゾーンとデータベースの設定

基本的な設定は、settings.pyに記述されています。
タイムゾーンを日本になるように書き換えます。

```
# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/

LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'
```

タイムゾーンの設定後に、ブラウザで確認してみると、日本語設定に切り替わっていることが確認できます。

![django-runserver-ja.png](https://qiita-image-store.s3.amazonaws.com/0/314263/a7121330-f75e-73d9-9186-e1e9716afca1.png)

Djangoで開発する際は、標準設定としてSQlite3が設定されています。
今回は、SQlite3を使用して開発をしてみようと思います。

```
# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
```

SQlite3を使用するので、特に設定の変更を行わずに、migrateを実行します。

```
(env-test) C:\Users\username\django\django_test> python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... 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 sessions.0001_initial... OK
```

上記のようなメッセージが表示されれば成功です。

### Django管理画面

次に、Djangoの管理画面にアクセスするためのスーパーユーザーを作成します。
createsuperuserコマンドで作成することができます。

```
(env-test) C:\Users\username\django\django_test>python manage.py createsuperuser
ユーザー名 (leave blank to use 'username'): admin
メールアドレス: django-test@test.co.jp
Password:
Password (again):
Superuser created successfully.
```

※メールアドレスは適当なもので問題ありません。

実際に作成したアカウントで管理画面にログインしてみます。
Djangoでは、デフォルトで/adminにアクセスすると管理画面に進むことができます。

![django-admin-top.png](https://qiita-image-store.s3.amazonaws.com/0/314263/a8ae3a9b-45b3-ed10-0d56-44f17263eeb9.png)

先ほど作成したスーパーユーザーでログインします。

![django-admin-login-before.png](https://qiita-image-store.s3.amazonaws.com/0/314263/aba677b7-4fc9-33e5-431c-dc77efcf17f4.png)

![django-admin-login-after.png](https://qiita-image-store.s3.amazonaws.com/0/314263/2b2fa3db-c46b-eb40-2414-684e3c73cdc9.png)

管理画面から、ユーザの追加やテーブルの操作等を行うことができます。

### アプリケーションの作成、設定

これまでの作業で、プロジェクトの作成と管理画面へのアクセスを確認することができました。
このプロジェクトの中にアプリケーションを構築してみようと思います。

アプリケーションを作成する場合は以下のコマンドで作成することができます。

```
(env-test) C:\Users\username\django\django_test>python manage.py startapp test_app
```

上記を実行すると、アプリケーションのひな型となるディレクトリが作成されます。
今回はtest_appという名前でアプリケーションを作成してみました。

作成したアプリケーションに処理を書いて動作を確認するところから始めてみます。

↓test_app/views.py

```
from django.http import HttpResponse

def index(request):
    return HttpResponse("動作確認です")
```

ビューの記述が終わったら、エンドポイントを設定します。
今回作成したtest_appディレクトリ直下にurls.pyを新規で作成します。

↓test_app/urls.py

```
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
]
```

あわせてルートにあるurls.pyも修正します。
↓urls.py

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('test_app/', include('test_app.urls')),
]
```

上記の設定で、ローカルの場合、http://localhost:8000/test_app/ に接続することで、画面上に「動作確認です」の文字が表示されればOKです。

動作の確認ができたので、viewsをGETとPOSTに分けて書いてみます。
クラスベース汎用ビューを参考にしつつ作成してみます。
views.pyを画面単位で分割していきたいのでviewsディレクトリを作成します。

test_app/views/test1_views.py
今回は元々あったtest_app/views.pyをtest1_views.pyにリネーム、移動して使っていきます。

```
from django.http import HttpResponse
from django.views.generic import View   # 一般的なViewを使用してみる

class test1_views(View):
    def get(self, request):
        return HttpResponse("動作確認です！GET！")

    def post(self, request):
        return HttpResponse("動作確認です！POST！")
```

クラスベース汎用ビューに書き換えたことでurls.pyにも修正を入れます。
test_app直下のurls.pyを書き換えます。ルートのurls.pyはそのままです。
import文で今回作成したtest1_viewsを読み込んでpathの設定に使用します。

```
from django.urls import path
from test_app.views.test1_views import test1_views

urlpatterns = [
    path('test1_views.html', test1_views.as_view(), name='test1_views'),
]
```

上記の設定で、ローカルの場合、http://localhost:8000/test_app/test1_views.html に接続するできるようになります。

このひな形を使えば、viewsディレクトリに新規でファイルを作成していけば画面単位で分かりやすくエンドポイントを増やしていけそうです。

次は、テンプレートについて触れてみます。
test1_appの直下にtemplatesディレクトリを作成し、その中にtest1_views.htmlを作成します。
動作確認のみのためmetaタグ等は省略しています。

```
<!DOCTYPE html>
<html lang="ja">

<head>
    <title>test1</title>
</head>

<body>
    <div>
        <h1>テンプレートの表示確認！</h1>
    </div>
</body>

</html>
```

静的ファイルのパスを設定します。

```
TEST_APP_STATIC_DIR = os.path.join(BASE_DIR, 'test_app/templates')

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [TEST_APP_STATIC_DIR],
        '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',
            ],
        },
    },
]
```

最後にviewを修正して、先ほど作成したHTMLファイルを参照するように変更します。

```
class test1_views(View):
    def get(self, request):
        # GETの処理を変更してみる
        return render(request, 'test1_views.html')
```

これでGET送信時にレンダリングされるようになりました。

## おわりに

PythonのDjangoフレームワークを用いてWebアプリ開発を始めるためのセットアップを行ってみました。実際にディレクトリ構成等を検討して、開発しやすいスケルトンにしてアプリ開発に用いてみたいです。

明日の記事は @ytakadama0922 さんです。よろしくお願いいたします。

ウェブクルーでは一緒に働いていただける方を随時募集しております。
お気軽にエントリーくださいませ。

[開発エンジニアの募集](https://hrmos.co/pages/1004681658307198976/jobs/0000005)
[フロントエンドエンジニアの募集](https://hrmos.co/pages/1004681658307198976/jobs/0000001)