Djangoメモ

DockerでDjango環境を作成するメモ。

参考：
　[DjangoにPostgreSQLを適用する](https://qiita.com/shigechioyo/items/9b5a03ceead6e5ec87ec#django%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B)
　[Django Girls Tutorial](https://djangogirlsjapan.gitbooks.io/workshop_tutorialjp/)

#Django用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/
```

```:requirements.txt
Django>=1.8,<2.0
psycopg2
```

```:イメージのビルド
docker build ./ -t django_test
```

#プロジェクトを作成
ホスト側に任意のディレクトリを作成し、そこに「/code」ディレクトリをマウントし、
mysiteというプロジェクトを作成する。

```:プロジェクトの作成
docker run --name django_web -v `pwd`:/code django_test django-admin startproject mysite .
```

#settings.pyの修正
mysite/settings.pyを修正する。

```:タイムゾーンの修正
LANGUAGE_CODE = 'ja-JP'

TIME_ZONE = 'Asia/Tokyo'

USE_TZ = False
```

```:ホスト許可の修正
ALLOWED_HOSTS = ['ホスト名']
```


```:データベースの修正（postgresql）
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2'),
        'NAME': 'DB名', 
        'USER': 'ユーザー名',
        'PASSWORD': 'パスワード',
        'HOST': 'ホスト名',
        'PORT': 'ポート',
    }
}
```

#コンテナ起動
```:コンテナ起動
docker run -d --name django_web -v `pwd`:/code -p 8000:8000 django_web python3 manage.py runserver 0.0.0.0:8000

#djangoのログを確認するには
docker logs コンテナID
```

http://IPアドレス:8000/
にアクセスして以下表示されることを確認。
「うまくいった！
おめでとうございます、Djangoで出力された最初のページです。」

#アプリケーションの作成
##blogアプリケーションの作成
manage.pyのあるディレクトリで以下実行。

```:blogアプリケーション作成
python manage.py startapp blog
```

psycopg2-binaryをインストールしろとのエラーが出る場合は以下実行。

```:psycopg2-binaryインストール
pip install psycopg2-binary
```

##settings.pyの修正
アプリケーションとしてblogを追加する。

```:settings.pyの修正
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',
)
```

##モデル用テーブルの作成
```:モデル用テーブルの作成
python manage.py makemigrations blog
python manage.py migrate blog
```
postgresqlにモデル用のテーブルが作成された。

#Django admin
##作成したモデルをadminページから見れるようにする。
blog/admin.pyを以下に置き換える。

```python:admin.py
from django.contrib import admin
from .models import Post

admin.site.register(Post)
```

http://ipアドレス:8000/admin/ で管理ページにアクセスできる。

##superuserの作成
```:superuserの作成
python manage.py createsuperuser
```

以下設定する。
Username: 
Email address: 
Password:
Password (again):

管理ページに行って、ユーザー、パスワードを入力するとログインできる。

#Django urls

```python:mysite/urls.py
from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'', include('blog.urls')),
]
```
Djangoは 'http://IPアドレス:8000/' に来たリクエストはblog.urlsへリダイレクトするようになり、それ以降はそちらを参照するようになる。

blogの方のurls.pyを編集する。

```python:blog/urls.py
urlpatterns = [
    url(r'^$', views.post_list, name='post_list'),
]
```

'http://IPアドレス:8000/' に来たリクエストに対して、views.post_listを返すように指定していることになる。

#Django view
blog/views.pyを編集する。

```python:blog/views.py
from django.shortcuts import render

def post_list(request):
    return render(request, 'blog/post_list.html', {})
```

render メソッドは blog/post_list.html というテンプレートファイルを使って、引数で受け取った request の内容を出力する。

#テンプレートの作成
まずblogディレクトリに templates という新しいディレクトリを作成する。
次に、templatesディレクトリの中に、blogというディレクトリを作成する。
そこにpost_list.htmlを作成する。

```html:blog/templates/blog/post_list.html
<html>
    <head>
        <title>Django Girls blog</title>
    </head>
    <body>
        <div>
            <h1><a href="">Django Girls Blog</a></h1>
        </div>

        <div>
            <p>published: 14.06.2014, 12:14</p>
            <h2><a href="">My first post</a></h2>
            <p>Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
        </div>

        <div>
            <p>published: 14.06.2014, 12:14</p>
            <h2><a href="">My second post</a></h2>
            <p>Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut f.</p>
        </div>
    </body>
</html>
```