Djangoとは
Python製のWEBアプリケーションフレームワーク。 WEBアプリケーションフレームワークとは、WEBアプリケーションを効率的に開発するための機能をまとめたもの。
Python系のWEBアプリケーションフレームワークには、他にも FlaskやBottle、Pyramidなど軽量なWEBアプリケーションもある。
Djangoは、機能が多様で、WEBアプリケーション開発に必要な機能が一通り揃っていることが好まれ、Python系のWEBアプリケーションフレームワークの中でも利用者が多い。 Djaongは以下の要素で構成されている。
URLルーティング
DjaognにおいてURLと、そのURLにアクセスした際の対する処理を定義する仕組み。
ルーティングは、下記の例にあるように、urls.py
で定義する。
path関数は、第一引数に指定したURLのパスに対応する処理を、第二引数に指定する。
下記の例では、“http://example.com/admin"にアクセスした際に、admin.site.urls
を呼び出すようになっている。
また、“http://example.com/app_ur/admin"にアクセスした際に、アプリケーションの urls.py
を呼び出すようになる。
※ includeメソッドを使用すると、アプリケーションのurls.py
を呼び出すことができる。
- プロジェクト/urls.py
from django.contrib import admin
from django.urls import path, include
from .views import hello_fuction_view
from .views import HelloClassView
urlpatterns = [
path('admin/', admin.site.urls),
path('app_url/', include('application_name.urls')),
]
- アプリケーション/urls.py
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
ビュー
DjangoにおいてWEBサイトの見た目を定義する要素。
ルーティングから受けっとたリクエスト情報を元に、レスポンスを返す。 ビューによりリクエストの内容に応じた、WEBページが表示できる。
ビューはviews.py
に定義する。
ビューには関数ベースビューと、クラスベースビューがある。。
関数ベースビュー
HTTPリクエストを引数に、それに対するレスポンスを返す関数
以下は、リクエストを受けた際に、Hello Worldをレスポンスとして返すビューの例。
from django.http import HttpResponse
def hello_fuction_view(request):
return HttpResponse("<h1>Hello World!</h1>")
クラスベースビュー
Djangoにクラスとして予め実装されているビューのこと。 クラスビューにはデフォルトで基本機能が実装されているので、 関数ビューよりも、簡潔に記述できる。
以下は、リクエストを受けた際に、hello_templateをレスポンスとして返すビューの例。
from django.views.generic import TemplateView
class HelloClassView(TemplateView):
template_name = "hello_template.html"
urls.pyからビューを呼び出す
urls.py
、URLに応じて呼び出すビューを指定する。
from django.contrib import admin
from django.urls import path, include
# ビューをインポート
from .views import hello_fuction_view
from .views import HelloClassView
urlpatterns = [
# 関数ビューを呼び出す
path('function_view/', hello_fuction_view),
# クラスビューを呼び出す
path('class_view/', HelloClassView.as_view()),
]
フォーム
Djangoにおいてフォーム項目の書式(幅、プレースホルダ)や、フォーム項目に入力された値のチェック(バリデーション)などのフォーム項目に持たせる機能を定義する要素。
forms.py
に定義する。
from django import forms
class SupportForm(forms.Form):
name = forms.CharField(label='名前', max_length=30)
email = forms.EmailField(label='メールアドレス')
title = forms.CharField(label='タイトル', max_length=30)
message = forms.CharField(label='メッセージ', widget=forms.Textarea)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['name'].widget.attrs['class'] = 'form-control col-9'
self.fields['name'].widget.attrs['placeholder'] = '田中太郎'
self.fields['email'].widget.attrs['class'] = 'form-control col-11'
self.fields['email'].widget.attrs['placeholder'] = 'taro@sample.com'
self.fields['title'].widget.attrs['class'] = 'form-control col-11'
self.fields['title'].widget.attrs['placeholder'] = 'タイトル'
self.fields['message'].widget.attrs['class'] = 'form-control col-12'
self.fields['message'].widget.attrs['placeholder'] = 'メッセージ'
モデル
DjangoにおいてDBに登録するデータの定義や、DBへの操作する要素。 ビューから受け取ったDBへの操作要求をDBに実行し、実行結果をビューに返す。
models.py
に定義する。
from django.db import models
class SupportModel(models.Model):
name = models.CharField(max_length=30)
email = models.CharField(max_length=30)
title = models.CharField(max_length=30)
message = models.CharField(max_length=30)
support_date = models.DateField()
def __str__(self):
return self.title
データベースマイグレーション
Djangoにおいてmodels.pyに定義した内容をデータベースに反映させる機能。 マイグレーションは下記の流れで行われる。
- model.pyからマイグレーションファイルという中間ファイルを生成
- マイグレーションファイルを読み取り、SQLに変換しデータベースに適用する
model.pyの内容を変更する度にマイグレーションが必要となる。
テンプレート
雛形となるHTMLファイル。 Djangoテンプレート言語という記法に基づいた特殊文字列を記載することが可能。
Djangoテンプレート言語を使用することで、置換文字列や、制御文、繰り返し分をHTMLファイル中に埋め込むことができ、WEBページの内容を動的に変更することが可能。
{% extends "base_generic.html" %}
{% block title %}{{ section.title }}{% endblock %}
{% block content %}
<h1>{{ section.title }}</h1>
{% for story in story_list %}
<h2>
<a href="{{ story.get_absolute_url }}">
{{ story.headline|upper }}
</a>
</h2>
<p>{{ story.tease|truncatewords:"100" }}</p>
{% endfor %}
{% endblock %}
https://docs.djangoproject.com/ja/3.0/topics/templates/
変数
変数はDjangoのソースコード中に定義した変数の値を置換したものを表示する。
{{ 変数名 }}
のような形式で指定する。
フィルタ
変数の表示内容をカスタマイズする機能。
{{ 変数名|フィルタ }}
のような形式で指定する。
下記は日付の表示形式をカスタマイズするフィルタの例。
{{ my_date|date:"Y-m-d" }}
タグ
テンプレートファイルの機能を便利にするもの。 Djangoには様々な組み込みタグがあり、 一般的なプログラミング言語にあるような、制御文や繰り返し文を使用したテンプレートの制御も可能。 タグは {% タグ名 %} のように記載する。
if-elseタグ
{% if user.is_authenticated %}
Authenticated OK.
{% else %}
Authenticated NG.
{% endif %}
forタグ
<ul>
{% for item in object_list %}
<li>{{ item.name }}</li>
{% endfor %}
</ul>
block-extendsタグ
他のテンプレートファイルの内容を継承する際に利用する。
extendsタグに他のテンプレートファイル名を指定すると、そのテンプレートファイルの内容を継承することができる。
自身のテンプレートファイルのblockタグで記載した内容を、 ベースとなるテンプレートファイルにblockタグで定義した箇所に置換できる。
- base.html
<head>
<title>{% block title %}{% endblock %}</title>
{% block head %}{% endblock %}
</head>
- index.html
{% extends 'base.html' %}
{% block title %}
ページタイトル
{% endblock %}
{% block header%}
<h2>ヘッダメッセージ</h2>
コンテンツの内容を記載
{% endblock %}
Djangoの設定
settings.py
でDjango全体の設定をすることができる。
設定項目には以下のようなものがある。
-
BASE_DIR
ベースディレクトリ(Djangoのプロジェクトディレクトリ) のファイルパスの設定
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-
SECRET_KEY
Djangoの秘密鍵の設定
SECRET_KEY = '+@gc2_!a39wo30b1ayc&$*d6m0s131_db5*qgmltm)@j!(f-iy'
-
DEBUG
デバッグモードの設定 (エラーが出た際になどにWEBサイトに詳細なメッセージが表示される)
DEBUG = True
- ALLOWED_HOSTS
アクセス許可をするホストの設定 (※ 通常は公開するWEBサーバのドメイン名を指定する)
# 全てのホストからのアドレスを許可する場合
ALLOWED_HOSTS = ['*']
# WEBサーバのドメインと、localhostからのアクセスを許可場合
ALLOWED_HOSTS = ['exsample.com', 'localhost']
-
INSTALLED_APPS
利用するDjangoの機能の設定するための項目。
# django.contrib.admin(管理サイト用WEBアプリケーション)を利用する場合
INSTALLED_APPS = [
'django.contrib.admin'
]
-
MIDDLEWARE
ミドルウェアの設定(セッションの維持などの設定)を行う項目
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
]
-
ROOT_URLCONF
WEBサイトのルートとなるURLの設定を行う項目
ROOT_URLCONF = 'sample_project.urls'
-
TEMPLATES
テンプレートファイルの設定(ディレクトリのファイルパスの設定など)を行う項目
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR, 'templates'],
'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',
],
},
},
]
-
WSGI_APPLICATION
PythonとDJANGOとなるWSGIファイルのファイルパスを設定を行う項目
WSGI_APPLICATION = 'sample_project.wsgi.application'
-
DATABASES
Djangoが使用するDBの設定 (DBエンジン、ファイルパスなど)を行う項目
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'django_db',
'USER': os.environ.get('DB_USER'),
'PASSWORD': os.environ.get('DB_PASSWORD'),
'HOST': '',
'PORT': '',
}
}
-
AUTH_PASSWORD_VALIDATORS
パスワードチェックの規則の設定を行う項目
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
-
LANGUAGE_CODE
使用する言語の設定を行う項目
LANGUAGE_CODE = 'ja'
-
STATIC_URL
WEBサーバがCSS、JavaScriptなどの静的ファイルを読み取るために、静的ファイルが保存されているURLのパスを指定する項目
STATIC_URL = '/static/'
-
STATIC_ROOT
静的ファイルを一箇所にまとめるコマンド
manage.py collectstatic
を実行したときに静的ファイルがまとめられるディレクトリのパスを指定する項目。
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
-
STATICFILES_DIRS
Djangoが静的ファイルを読み取るために、静的ファイルが保存されているのディレクトリのパスを指定する項目。
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
Django関連の開発環境
Nginx
WEBサーバの機能を提供するOSS。 大量のリクエストアクセスをさばくことに長けている。
Gunicorn(Green Unicorn)
PythonのWGSGIのひとつ。 WSGI(Web Server Gateway Interface)とは、WEBサーバとWEBアプリケーションを接続させるためのインターフェースの仕様である。
https://wsgi.readthedocs.io/en/latest/
Bootstrap
BootstrapはTwitter社が開発したCSSの「フレームワーク」。 WEBページでよく使われるフォーム・ボタン・メニューなどの部品がテンプレートとして用意されている。
Djangoの環境の構築
環境構成
以下の環境でDjango環境を作成する。
- OS : CentOS 7.6
- DB : PostgreSQL
- WEBサーバ : Nginx
パッケージのインストール
$ yum install -y python3-pip python3-dev
$ yum install -y libpq-dev postgresql postgresql-contrib
$ yum install -y nginx
DBの設定
Django用に使用するDB(django_db)とユーザ(django_user)を作成する。
$ sudo -u postgres psql
> CREATE DATABASE django_db;
> CREATE USER django_user WITH PASSWORD 'password';
> ALTER ROLE django_user SET client_encoding TO 'utf8';
> ALTER ROLE django_user SET default_transaction_isolation TO 'read committed';
> ALTER ROLE django_user SET timezone TO 'UTC';
> GRANT ALL PRIVILEGES ON DATABASE django_db TO django_user;
# DBが作成されていることを確認
> \l
# ユーザが作成されていることを確認
> SELECT * FROM pg_shadow;
> \q
pythonの仮想環境の構築
$ /usr/local/bin/pip3 install virtualenv
$ mkdir -p /opt/virtualenv
$ cd /opt/virtualenv
$ virtualenv django_env
Djangoのインストール
$ source /opt/virtualenv/django_env/bin/activate
$ pip install django gunicorn psycopg2-binary
Djangoプロジェクトの作成
$ mkdir -p /opt/django
$ cd /opt/django/
$ django-admin startproject sample_project
ディレクトリの作成
静的ファイルと、テンプレートファイルを保存するディレクトリを作成する。
$ mkdir -p /opt/django/sample_project/static
$ mkdir -p /opt/django/sample_project/templates
Djangoの設定変更
settings.py
に対して、デフォルトで作成されたものから、以下の点を変更する。
- アクセスする許可するホストを変更
ALLOWED_HOSTS = ['example.com', 'localhost']
- テンプレートのディレクトリを変更。
TEMPLELATEのDIRS
を以下のように変更する。
これにより、プロジェクトディレクトリ直下のtemplatesというディレクトリがテンプレートに指定される。
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR, 'templates'],
'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',
],
},
},
]
- DATABASEをPostgreSQLに設定
デフォルトだとSQLiteが設定されているので、postgresqlに変更する。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'django_db',
'USER': 'django_user',
'PASSWORD': 'password',
'HOST': '',
'PORT': '',
}
}
- 言語とタイムゾーンを日本環境に設定する
日本語環境に設定するため、以下のように設定を行う。
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
- 静的ファイルのパスを設定
静的ファイルを配置するパスをプロジェクト直下のstaticディレクトリに設定する。
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
Djangoアプリケーションの作成
以下のコマンドを実行するとプロジェクトのディレクトリ直下にアプリケーション用のディレクトリが作成される。
$ cd /opt/django/sample_project
$ python manage.py startapp sample_application
データベースマイグレーション
$ python manage.py makemigrations
$ python manage.py migrate
Djangoの管理者ユーザを作成
管理画面にログインする際の管理者ユーザー (スーパーユーザー)を設定する。
$ python manage.py createsuperuser
# 以下のように入力する
> ユーザー名 (leave blank to use 'root'): admin
> メールアドレス: admin@test.com
> Password: admin_1234
> Password (again): admin_1234
> Superuser created successfully.
静的ファイルを作成
/opt/django/sample_project/staticにcssなどの静的ファイルを移動させる。
$ python manage.py collectstatic
ファイアウォール設定の解除
ポート8080を開放する。
$ firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" port protocol="tcp" port="8080" accept"
gunicornをsystemdに登録
下記の2ファイルを作成。
- /etc/systemd/system/gunicorn.socket
Nginxからアクセスを受けるソケットの設定。
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
User=www-data
[Install]
WantedBy=sockets.target
- /etc/systemd/system/gunicorn.service
socketからアクセスを受けた時にgunicornを起動させる設定を行う。
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=root
Group=root
WorkingDirectory=/opt/web/request_generator
ExecStart=/opt/web/request_generator/request_generator_venv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
request_generator.wsgi:application
[Install]
WantedBy=multi-user.target
gunicornをsystemdに登録して、起動させる。
$ systemctl enable gunicorn.socket
$ systemctl start gunicorn.socket
https://docs.gunicorn.org/en/stable/deploy.html
Nginxの設定
以下のファイルを作成する。
- /etc/nginx/conf.d/gunicorn.conf
ポート8080でNginxにリクエストした際に、Gunicornのソケットファイル(gunicorn.sock)にリクエストをプロキシする設定を実施。
server {
listen 8080;
server_name example.com # WEBサーバのドメイン名
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /opt/django/sample_project; # djangoのプロジェクトディレクトリ
}
location / {
proxy_pass http://unix:/run/gunicorn.sock;
#proxy_pass http://127.0.0.1:8000;
}
}
設定を反映させるため、Nginxを再起動する。
$ systemctl enable nginx.service
$ systemctl restart nginx.service
WEBサーバを経由してWEBサイトを表示
WEBブラウザで下記のアドレスにアクセスすると、DJANGOのサンプルページにアクセスできる。
http://exsample.com:8080