ホーム >  Python > Django >  投票アプリを作る その3モデルとView・Templateの連携(Django)

投稿日:   |  最終更新日:

投票アプリを作る その3モデルとView・Templateの連携(Django)

DjangoPython

Djangoで簡単な投票アプリを作成します。モデルを準備しましたので、データをviewやTemplateで表示してみます。

投票アプリ

Webサイトのページから投票できる簡単な投票アプリを作成します。前回は定義したモデルを操作するため、管理サイトをカスタマイズしました。今回は、viewとurlを使います。

viewは、一般的なMVCでいうとコントローラに相当します。MVCのViewに相当するものは、Djangoではviewから呼び出すtemplateです。

仕様

Webページにボタン等のフォームを配置します。ユーザが入力を終え、送信ボタンをクリックしたタイミングでモデル(テーブル)への登録処理を行います。

準備

当サイトでは、Vagrantでゲスト環境(仮想環境)を作ってDjangoを動かいていますが、それ以外の環境でも操作方法はだいたい同じです。

①Djangoプロジェクトを生成します。

VagrantのDjangoで作るWebアプリケーション(その1 プロジェクト生成)

②Djangoアプリケーションを作ります。

VagrantのDjangoで作るWebアプリケーション(その2 プロジェクトの初期設定)

③投票アプリのモデルを定義します。

投票アプリを作る その1モデルの定義、管理サイトの表示(Django)

④Djangoの管理ページからモデルを編集します。

投票アプリを作る その2管理サイト上のモデル編集(Django)

環境

OS CentOS 7.1.1503
pyenv 1.1.3-5-g7dae197
Anaconda 3-4.3.0
MariaDB 5.5.52-1.el7
Apache 2.4.6
mod_wsgi 4.5.14
Django 1.11.3

投票アプリ概要

①以下のようなDjangoアプリ構成を作ります。プロジェクト名が「pj1」で、アプリケーション名が「users」です。プロジェクトの設定は済ませたものとします。赤字のファイルは、今回変更する部分です。

  • pj1/
  • pj1/
  • __init__.py
  • settings.py
  • urls.py
  • wsgi.py
  • users/
  • __init__.py
  • admin.py
  • apps.py
  • urls.py
  • views.py
  • models.py
  • templates/

viewの追加

viewはユーザからHttpRequestを受け取って、HttpResponseを返す関数です。

①usersディレクトリのviews.pyに以下の内容を記述します。

from django.http import HttpResponse


def index(request):
    return HttpResponse("Hello, world. You're at the polls index.")

解説

def index(request):

viewメソッドは第1引数に必ずHttpRequestクラスを受け取ります。

    return HttpResponse("Hello, world. You're at the polls index.")

また、戻り値としてHttpResponseクラス(もしくはそれを継承したクラス)を返す必要があります。


urlの設定

Djangoへのアクセス時には最初にROOT_URLCONF(デフォルトではproject/urls.py、今回の例ではpj1/urls.py)を確認します。そして、どのviewを呼び出すかを確認します。urlを設定すると、結果をブラウザから確認できるようになります。

まず、usrs(アプリケーション)ディレクトリのurls.pyを記述した後、pj1(プロジェクトディレクトリ)のurls.pyも記述します。

  • pj1/
  • pj1/
  • urls.py
  • 〜省略〜
  • users/
  • urls.py
  • 〜省略〜
  • templates/

urlの設定方法、概念がdjango1.8で大きく変わりました。

①usersディレクトリのurls.pyに以下の内容を記述します。

from django.conf.urls import url

from . import views


urlpatterns = [
    url(r'^$', views.index, name='index'),  # urlとviewの結びつけ
]

これで「users.views.index」とusersのurlが接続されました。しかしこの段階では、「users.urls」はroot_urlではないためまだブラウザから確認することはできません。

②pj1ディレクトリの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('users.urls', namespace = 'users')),  # urlと他のurlpatternsとの結びつけ
]

root_url」を更新した状態です。これで「polls/」に一致するurlは「users.urls」を呼び出すようになり,ブラウザで確認できるようになります。

解説

urls.pyにはurlpatternsという配列が設定されています。

urlpatterns = [
〜(省略)〜
]

配列の要素はurl関数で追加していきます。url関数ではurlとview、もしくはurlと他のurlpatternsを結びつけます。

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^polls/', include('polls.urls')),  # urlと他のurlpatternsとの結びつけ
]

url関数の概要

url(r'^$', views.index, name='index'),
  • 第1引数にurlの正規表現を記述します。
  • 第2引数にview関数、もしくはinclude関数の戻り値を渡します。
  • 第3引数の name=’index’) はurlの逆引き用です。別viewへのリダイレクトやtemplate内でのリンクに使用します。
  • r”と書いていると正規表現ではなく「raw」文字列のことです。
  • \をエスケープ文字ではなくそのまま出力するようになります。

includeを使用した場合、matchした文字列を取り除いた部分を次のurlpatternsに渡します。

③簡易サーバーを起動して、ブラウザで確認してみましょう。

cd pj1
python manage.py runserver 0.0.0.0:8000

「http://localhost:8000」にアクセスします。

templateの利用

templateはhtml形式です。「apps/templates/apps/」以下に設置します。「{{ var }}」のように中括弧2つで囲むとpythonから渡された値を使用できます。

  • pj1/
  • pj1/
  • 〜省略〜
  • users/
  • views.py
  • 〜省略〜
  • templates/users/
  • index.html

また、「{% func %}」の形式でテンプレートタグと呼ばれる関数を実行することができます。

①通常のhtmlを使用して作成していきます。

<html>
<body>
  <p>Hello, world. You're at the polls index.</p>
  <p>template version!</p>
</body>
</html>

②viewを書き換えます。

from django.shortcuts import render


def index(request):
    return render(request, 'users/index.html')

解説

    return render(request, 'users/index.html')

render関数は、「request」と テンプレートパスを渡すとそのテンプレートを使用したレンダリング結果をHttpResponseとして返してくれます。


templateへの値渡し

ここまでで静的なページは作れるようになりました。次に動的なページを作ります。

  • pj1/
  • pj1/
  • 〜省略〜
  • users/
  • views.py
  • 〜省略〜
  • templates/users/
  • index.html

①viewを書き換えます。

from django.shortcuts import render


def index(request):
    return render(request, 'users/index.html', {
        'hoge': 'test string',
        'fuga': '<br>tag</br>',
    })

②テンプレートを書き換えます。受け取った値を表示させてみます。

<html>
<body>
  <p>Hello, world. You're at the polls index.</p>
  <p>template version!</p>
  <p>{{ hoge }}</p>
  <p>{{ fuga }}</p>
</body>
</html>

③簡易サーバーを起動して、ブラウザで確認してみましょう。

cd pj1
python manage.py runserver 0.0.0.0:8000

「http://localhost:8000」にアクセスします。

解説

    return render(request, 'users/index.html', {
        'hoge': 'test string',
        'fuga': '<br>tag</br>',
    })

renderの第3引数に辞書を渡すことでtemplateに値を渡すことができます。

fugaは<br>タグがエスケープされて出力されてしまっています。セキュリティ的には嬉しいですが,タグを出力したい場合は、「django.utils.html.mark_safe」関数を使用します。

エスケープする場合は、以下のように記述します。

from django.shortcuts import render
from django.utils.html import mark_safe


def index(request):
    return render(request, 'polls/index.html', {
        'hoge': 'test string',
        'fuga': '<br>tag</br>',
        'piyo': mark_safe('<br>tag</br>'),
    })

template内で渡された値を使う場合は{{ var }}の形式で書きます。

  <p>{{ hoge }}</p>
</body>
</html>


次回

次回は、ビューとモデルを連携します。


トラックバック用のURL
プロフィール

名前:イワサキ ユウタ 職業:システムエンジニア、ウェブマスター、フロントエンドエンジニア 誕生:1986年生まれ 出身:静岡県 特技:ウッドベース 略歴 20

最近の投稿
人気記事
カテゴリー
広告