Django：Herokuにデプロイするまで

Djangoのwebappのデプロイまでの備忘録。
==

virtualenvはPythonの仮想環境を作るためのライブラリ

pip経由でインストール
`$ pip install virtualenv`

クリーンな仮想環境を作る
`$ virtualenv [env_name]`

仮想環境を有効化する
`$ source [env_name]/bin/activate`

仮想環境を無効化する
`$ deactivate`

最新バージョンのpipがインストールされていることを確認する
`$ pip install --upgrade pip`

Djangoインストール
`$ pip install django==1.11`

プロジェクト作成
コマンドのコマンドの最後にピリオド (.) がある
これば、現在の作業ディレクトリにDjangoをインストールするということを示す
`$ django-admin startproject [project_name] .`

manage.py はサイト管理用のスクリプト
settings.pyは、サイトの設定ファイル



```[project_name]/settings.py
LANGUAGE_CODE = 'ja-JP'
TIME_ZONE = 'Asia/Tokyo'
USE_TZ = False
```

sqlite3というデータベースを使う

```[project_name]/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
```

データベースをこのサイトに作成する
`$ python manage.py migrate`

これでデータベースができた
サーバーを動かして、Webサイトがうまく動いているか確認する
`$ python manage.py runserver`

http://127.0.0.1:8000/
を開いてサイトがきちんと動いているか確認する

プロジェクトの中に別のアプリケーションを作る
`$ python manage.py startapp [app_name]`

アプリケーションを作ったら、Djangoにそれを使うように伝える
>[project_name]/settings.pyのINSTALLED_APPSをみつけて'[app_name]'という一行を追加する

[app_name]/models.py（ブログポストを定義する場所）に次のコードを書く

```[app_name]/models.py
from django.db import models
from django.utils import timezone

class Post(models.Model):
    author = models.ForeignKey('auth.User')
    title = models.CharField(max_length=200)
    text = models.TextField()
    created_date = models.DateTimeField(
            default=timezone.now)
    published_date = models.DateTimeField(
            blank=True, null=True)

    def publish(self):
        self.published_date = timezone.now()
        self.save()

    def __str__(self):
        return self.title
```
- models.CharField - テキスト数を定義するフィールド
- models.TextField - 制限無しの長いテキスト用
- models.DateTimeField - 日付と時間のフィールド
- models.ForeignKey - 他のモデルへのリンク

（詳細）https://docs.djangoproject.com/ja/1.11/ref/models/fields/#field-types

ブログを公開するメソッド
def publish(self):

メソッドは通常何かをreturnする
例えば、ここでは、__str__()を呼ぶと、ポストの表題のテキスト(string)が返ってくる

次に、新しいモデルをデータベースに追加する
`$ python manage.py makemigrations [app_name]`

新しいモデルをデータベースに追加する
`$ python manage.py makemigrations [app_name]`
Djangoがデータベースに入れる為の移行ファイルを作ってくれている
`$ python manage.py migrate [app_name]`

作成したポストを追加、編集、削除するのにDjango adminを使う

```[app_name]/admin.py
from django.contrib import admin
from .models import Post

admin.site.register(Post)
```
モデルをadminページで見れるようにするには、モデルをadmin.site.register(Post)で登録する必要がある

`$ python manage.py runserver`
 http://127.0.0.1:8000/admin/ 

ログインするには、superuser （サイトの全てを管理するユーザー）を作る必要がある
ユーザーネーム（小文字スペース無し）、メールアドレスとパスワードなどを入力する

```
$ python manage.py createsuperuser
Username: admin
Email address: admin@admin.com
Password:
Password (again):
Superuser created successfully.
```

superuserでログインすると、Django admin ダッシュボードが開く

(Django adminについて詳細)https://docs.djangoproject.com/ja/1.11/ref/contrib/admin/

## Deploy!
requirements.txtファイルを作成する
これは、サーバーにどんなPythonパッケージがインストールされる必要があるか、Herokuに伝えるもの

まず、Herokuを使うために必要ないくつかのパッケージをインストールしておきましょう
`$ pip install dj-database-url gunicorn whitenoise`
`$ pip freeze > requirements.txt`

これで、requirements.txtとよばれるファイルが作成される
これには、必要なパッケージのリスト（どんなPythonライブラリを使っているかといった情報）が書かれている

pip freeze は、virtualenvにインストール済みの全てのPythonライブラリを一覧にして出力する

ファイルを開いて、最終行に次の1行を追加する
`psycopg2==2.5.4`

次に、Procfileが、どのコマンドを実行してウェブサイトをスタートするかHerokuに伝える
エディタを開いて、 [dir_name]にProcfileという名前のファイルを作成する
ファイルに次のとおり入力する
`web: gunicorn [project_name].wsgi`

これは、web アプリケーションをデプロイしようとしていること、
そしてgunicorn [project_name].wsgiというコマンドを実行すること
でデプロイすることを意味している
（gunicornは、Djangoのrunserverコマンドのもっとパワフルなもの）

次に、エディタを開いて、 [dir_name]にruntime.txtという名前のファイルを作成する
`python-3.6.2`
を書く

コンピューター上のローカルとサーバーでは設定に違いがある
Herokuとコンピューターでは別のデータベースをそれぞれ使っている
そこで、別途ファイルを作成し、ローカル環境で動かすための設定を保存しておく必要がある

[project_name]/local_settings.pyというファイルを作成し、
その中で、DATABASE の設定をする
次のように記述する

```[project_name]/local_settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

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

DEBUG = True
```

[project_name]/settings.pyの最終行に、次のとおり追加する

```[project_name]/settings.py
import dj_database_url
DATABASES['default'] = dj_database_url.config()

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

ALLOWED_HOSTS = ['*']

STATIC_ROOT = 'staticfiles'

DEBUG = False

try:
    from .local_settings import *
except ImportError:
    pass
```

このファイルは、Herokuに必要な構成だけでなく、[project_name]/local_settings.pyファイルがある時にはローカルの設定にも重要な役割を果たす

次に、[project_name]/wsgi.pyファイルを開き、最終行に次のとおり追加する

```[project_name]/wsgi.py
from whitenoise.django import DjangoWhiteNoise
application = DjangoWhiteNoise(application)
```

`$ heroku login`

Herokuでは、Gitのリポジトリを使って、プロジェクトのファイルを管理する
[dir_name]に、.gitignoreという名前のファイルを作成する
次のとおりに記述する

```
myvenv
__pycache__
staticfiles
local_settings.py
db.sqlite3
*.py[co]
```

Git に local_settings.py は無視してアップロードしないように伝えている

次に、Gitのリポジトリを作成し、これまでの変更を記録する

```
$ git init
Initialized empty Git repository in ~/[dir_name]/.git/
```

`$ git status`
`$ git add -A .`
`$ git commit -m "first commit"`
`$ heroku create [website name]`

>`$ heroku apps:rename [website name]`(renameしたいとき)

`$ git push heroku master`

プロセスはProcfileと指定されている
(先ほど、プロセスタイプをwebと選んだため)
最後に、Herokuのウェブプロセスを起動する
`$ heroku ps:scale web=1`
`$ heroku open`

>デプロイに失敗したらログを見よう
`heroku logs --tail`

まだデータベースが空っぽの状態なので、ローカルにデータベースをセットアップした時のように、再度migrate コマンドを実行する

```
$ heroku run python manage.py migrate
$ heroku run python manage.py createsuperuser
```
ユーザーネームとパスワードを選ぶよう再度きいてくる
これは、オンライン上のウェブサイトのログインに必要となるログイン情報
ブラウザを再読み込みして、完了

参考：https://djangogirlsjapan.gitbooks.io/workshop_tutorialjp/django_urls/