Djangoとは
PythonによるWebアプリケーションフレームワークで、次の特徴があります。
- 高速開発
- 多数の便利な機能を装備
- テンプレートエンジン
- データベース(O/Rマッパー)
- 管理画面
- ユーザ認証
Djangoで最初のプロジェクトを作成
$ python --version # Pythonのバージョン確認 $ python -m django --version # Djangoのバージョン確認 $ django-admin startproject myapp # myappプロジェクトを作成 # settings.pyを修正 $ cd myapp/myapp $ diff settings.py.org settings.py 変更前: ALLOWED_HOSTS = [] 変更後: ALLOWED_HOSTS = ['*'] # どこからでもアクセスできるように $ cd .. $ python manage.py runserver # DjangoのWebサーバを起動
https://localhost:8000/ でWebサーバにアクセスできます。
DjangoでHelloWorld
$ cd ~/myapp $ python manage.py startapp bbs # bbsアプリケーションを作成 # views.py を修正 $ vi bbs/views.py from django.shortcuts import render from django.http import HttpResponse # HttpResponseをインポート def index(request): # index関数を呼び出し return HttpResponse('Hello Django') # Hello Django を返す # プロジェクト全体のルーティングを設定 $ vi myapp/myapp/urls.py from django.contrib import admin from django.urls import include, path # includeを追加 urlpatterns = [ path('bbs/', include('bbs.urls')), # URLと呼び出すファイルを紐付け path('admin/', admin.site.urls), ] # bbsアプリのルーティングを設定 $ vi myapp/bbs/urls.py # urls.pyファイル作成 from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), # /bbs/にアクセスの場合、views.pyのindex関数を呼び出す ] # bbsアプリをプロジェクトに登録 $ vi myapp/myapp/settings.py : INSTALLED_APPS = [ 'bbs.apps.BbsConfig', # bbsディレクトリのapps.pyに自動生成された「BbsConfigクラス」を登録 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] $ python manage.py runserver # DjangoのWebサーバを起動
https://localhost:8000/bbs/ でWebサーバにアクセスできます。
Djangoにテンプレートを追加
Djangoでは、テンプレートエンジンとして、Flaskと同じJinja2を採用しています。
# views.pyからテンプレートを呼び出す $ vi myapp/bbs/views.py from django.shortcuts import render from django.http import HttpResponse def index(request): return render(request, 'bbs/index.html') # bbsアプリのindex.htmlテンプレートを呼び出す # テンプレートファイルを作成 $ vi myapp/bbs/templates/bbs/index.html <style>body {padding: 10px;}</style> <h1>paiza bbs</h1>
テンプレートにデータを渡す
views.pyからテンプレートにデータを渡す
# myapp/bbs/views.py from django.shortcuts import render from django.http import HttpResponse def index(request): context = { 'message': 'Welcome my BBS', 'players': ['勇者', '戦士', '魔法使い', '忍者'] } return render(request, 'bbs/index.html', context) # contextという辞書を渡す
テンプレート側でデータを受け取って表示
<!-- myapp/bbs/templates/bbs/index.html --> <style>body {padding: 10px;}</style> <h1>paiza bbs</h1> {{ message }} <!-- message変数を表示 --> {% for player in players %} <!-- 直接Pythonのコードを記載できる --> {{ player }}はモンスターと戦った {% endfor %}
Djangoのモデルを作成
モデルとは
モデルは、データベースのレコードを Pythonのオブジェクトに割り当てる機能です。モデルを使えば、SQLを書かなくても、Pythonのコードでデータベースのレコードをオブジェクトとして操作できます。このように、オブジェクトでデータベースを操作するツールをORマッパー(Object-relational mapper)と呼びます。
照合順序
phpMyAdminでデータベースを作成する際、照合順序(文字コード:utf8_general_ci)を指定します。
※ MySQLのインストールがまだの場合、下記を参考にインストール
【Ubuntu 18.04 LTS】MySQLサーバを動かす
settings.pyで、データベース設定
# myapp/myapp/settings.py # Database # https://docs.djangoproject.com/en/2.0/ref/settings/#databases # Python3以降はmysqlclientを使用する #import pymysql #pymysql.install_as_MySQLdb() DATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), # } 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mydb', 'USER': 'root', 'PASSWORD': '', 'HOST': '127.0.0.1', 'PORT': '3306', } }
※ mysqlclientのインストールは、mysqlclient Python3でMySQLに接続 を参照
models.pyの作成
# myapp/bbs/models.py from django.db import models class Article(models.Model): # Articleモデルにcontentカラムを定義 content = models.CharField(max_length=200) def __str__(self): return self.content
マイグレーションとは
マイグレーションとは、データベースの中身を一括して移行したり変更する作業です。Djangoのマイグレーション機能を利用すると、データベースの変更を一度に行うことができます。
Djangoのマイグレーションは、2段階で行います。まず専用のコマンドを使って、モデルからマイグレーションファイルを作成します。その後マイグレーションを実行します。
$ python manage.py makemigrations bbs # マイグレーションファイルの作成 $ python manage.py migrate # マイグレーションを実行
Djangoの管理サイトを使用する
Djangoは、アプリケーションやデータベース・ユーザー情報のための管理機能を標準で備えています。
管理ユーザをコマンドで登録
$ cd myapp $ python manage.py createsuperuser Username: admin Email address: XXXX@gmail.com Password: ********** Password (again): ********* Superuser created successfully.
管理サイトにアクセス
$ python manage.py runserver # Webサーバ起動
下記URLで管理サイトにアクセスできるようになります。
https://localhost:8000/admin
管理サイトに、作成したArticleモデルを追加
# myapp/bbs/admin.py from django.contrib import admin from .models import Article admin.site.register(Article) # 掲示板のテーブルを管理できるよう登録
上記管理サイト上で、DBへレコードの追加等ができるようになります。
モデルのデータを一覧表示
ビューでモデルのデータを取り出す
# myapp/bbs/views.py from django.shortcuts import render from django.http import HttpResponse from .models import Article # 追加 def index(request): articles = Article.objects.all() # Articleオブジェクトのobjects.allメソッドを呼び出し context = { 'message': 'Welcome my BBS', 'articles': articles, # テンプレートにデータを渡す } return render(request, 'bbs/index.html', context)
テンプレートでモデルのデータを一覧表示
<!-- myapp/bbs/templates/bbs/index.html --> <style>body {padding: 10px;}</style> <h1>paiza bbs</h1> {{ message }} {% for article in articles %} <!-- articlesのデータをループで取り出し --> {{ article.content }} <!-- articleのcontentカラムを表示 --> {% endfor %}
データの詳細を表示(1)
ここでは、掲示板のサンプルデータを個別に表示するページを作成します。まずはルートで指定したデータをモデルから取り出します。
掲示板アプリのルーティング
ルート | コード | 表示するページ |
---|---|---|
(ドメイン名)/bbs/ | index() | 一覧表示 |
(ドメイン名)/bbs/<id> | detail() | 個別表示 |
(ドメイン名)/admin/ | admin.site.urls | 管理サイト |
urls.pyに/detailを追加
# myapp/bbs/urls.py from django.urls import path from . import views app_name = 'bbs' # 各ルートがbbsアプリのビューであることを指定 urlpatterns = [ path('', views.index, name='index'), # /bbs/にアクセスの場合、index関数を呼び出す path('<int:id>', views.detail, name='detail'), # 個別ページ(/bbs/<id>)のルートを追加 ]
views.pyを修正
# myapp/bbs/views.py from django.shortcuts import render, get_object_or_404 # 404エラーを出力するショートカット関数を追記 from django.http import HttpResponse from .models import Article def index(request): articles = Article.objects.all() context = { 'message': 'Welcome my BBS', 'articles': articles, } return render(request, 'bbs/index.html', context) def detail(request, id): # ルートで指定した値をid変数に格納 article = get_object_or_404(Article, pk=id) # 指定したidのオブジェクトがない場合は404エラーを出力 return HttpResponse(article)
https://localhost/bbs/1 等のidを指定することで個別ページを表示できます。
データの詳細を表示(2)
ルートで指定したデータをモデルから取り出すところまではできたので、それをテンプレートに渡して表示します。
views.pyにdetail関数を追加
# myapp/bbs/views.py from django.shortcuts import render, get_object_or_404 from django.http import HttpResponse from .models import Article def index(request): articles = Article.objects.all() context = { 'message': 'Welcome my BBS', 'articles': articles, } return render(request, 'bbs/index.html', context) def detail(request, id): article = get_object_or_404(Article, pk=id) context = { # contextディクショナリを追加 'message': 'Show Article ' + str(id), 'article': article, } return render(request, 'bbs/detail.html', context) # データを渡す
detail.htmlを表示
# index.htmlをコピーしてdetail.htmlを作成 $ cd ~/myapp/bbs/templates/bbs $ cp -p index.html detail.html
<!-- myapp/bbs/templates/bbs/detail.html --> <style>body {padding: 10px;}</style> <h1>paiza bbs</h1> {{ message }} {{ article.content }} <!-- 受け取ったarticle.contentを表示 --> 一覧 <!-- 一覧ページに戻るリンクを追加 -->
一覧表示から詳細表示にリンク
<!-- myapp/bbs/templates/bbs/index.html --> {% for article in articles %} {{ article.content }}, <a href="{% url 'bbs:detail' article.id %}">詳細</a> <!-- 個別ページへのリンクを表示 --> {% endfor %}