18a. Django入門1(Djangoの基本の理解)

Djangoとは

PythonによるWebアプリケーションフレームワークで、次の特徴があります。

  1. 高速開発
  2. 多数の便利な機能を装備
  3. テンプレートエンジン
  4. データベース(O/Rマッパー)
  5. 管理画面
  6. ユーザ認証

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 myapp
$ python manage.py runserver		# DjangoのWebサーバを起動

https://localhost:8000/ でWebサーバにアクセスできます。

DjangoでHelloWorld

$ cd myapp
$ python manage.py startapp bbs				# bbsアプリケーションを作成

# views.py を修正
$ vi myapp/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)を指定します。

settings.pyで、データベース設定

# myapp/myapp/settings.py
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
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',
    }
}

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を管理できるよう登録

上記管理サイト上で、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 = {											# 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 = {
        '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を表示 -->
<a href="{% url 'bbs:index' %}">一覧</a>	<!-- 一覧ページに戻るリンクを追加 -->

一覧表示から詳細表示にリンク

<!-- myapp/bbs/templates/bbs/index.html -->
{% for article in articles %}
       {{ article.content }},
       <a href="{% url 'bbs:detail' article.id %}">詳細</a>	<!-- 個別ページへのリンクを表示 -->
{% endfor %}

Webプログラミング入門

タイトルとURLをコピーしました