ホーム >  Python >  VagrantのDjangoで作るWebアプリケーション(その7 テンプレート作成)


Posted:2017/07/15 9:00:27 AM|Category : Python

VagrantのDjangoで作るWebアプリケーション(その7 テンプレート作成)

今回は、Djangoテンプレートを作成します。

テンプレートを作成

テンプレートとは、Viewのことで、HTMLファイルのテンプレートを作ります。Djangoでは「Django template language (DTL)」というテンプレートエンジンを使い、HTMLテンプレートに変数を埋め込むことでWebアプリケーションを作成します。今回は、IPアドレス管理アプリケーションに合わせてテンプレートを作成します。

DTL

DTLは、{{ }} や {% %} で括った値を変数やプログラミング関数として扱うことができます。

作業の流れ

  1. Bootstrapをダウンロードします。
  2. Bootstrapで利用するjQueryをダウンロードします。
  3. jQueryのファイルを、さきほどダウンロードしたboostrapディレクトリに移動します。
  4. Bootstrapディレクトリ配下の全ファイルを、pj1/app1/staticへ移動させます。
  5. DjangoからBootsrapを操作するdjango-bootstrap-formパッケージをインストールします。
  6. pj1/pj1/settings.pyにdjango-bootstrap-formを追記します。

準備

Vagrantでゲスト環境(仮想環境)を作ります。ゲスト環境の中にDjangoを構築します。その前に、以下の作業を終わらせましょう。

①Virtualboxをインストールします。Virtualboxのインストールまでで結構です。

VirtualBoxをインストールする for Ubuntu

②Vagrantをインストールします。centos7環境を作りますので、Vagrantのインストールのみ済ませてください。

Vagrantをインストールしてテスト環境を作る for Ubuntu

③Vagrantにcentos7環境を作ります。

VagrantでCentOS7 + Python + Django環境を作る(その1 仮想環境作成)

④VagrantにPython3をインストールし、「pyenv + virtalenv」を作ります。

VagrantでCentOS7 + Python + Django環境を作る(その2 Pythonとpyenv + virtalenv)

⑤VagrantにMariaDBをインストールして、DBを構築します。

VagrantでCentOS7 + Python + Django環境を作る(その3 MariaDB)

⑥VagrantにWebアプリケーションサーバーのnginxをインストールします。

VagrantでCentOS7 + Python + Django環境を作る(その4 nginx)

⑦VagrantにDjangoをインストールします。

VagrantでCentOS7 + Python + Django環境を作る(その5 Django + uWSGI)

⑧VagrantにDjangoプロジェクト生成します。

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

⑨生成したプロジェクトを初期設定します。また、データベースを初期化します。

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

⑩アプリケーションを生成し、モデルを作成します。

VagrantでDjangoで作るWebアプリケーションを作る(その3 アプリケーション・モデルの作成)

⑪必要であれば、DBのレコード情報を外部へ出力します。

VagrantでDjangoで作るWebアプリケーションを作る(その4 レコード情報を出力)

⑫DjangoのアプリケーションディレクトリのViewを定義します。

VagrantのDjangoで作るWebアプリケーション(その5 Viewの作成)

⑬DjangoにBootstrapをインストールします。

VagrantのDjangoで作るWebアプリケーション(その6 Bootstrapのインストール)

ホスト環境

OS Ubuntu 16.04.1 LTS 64bit
Virtualbox 5.1
Vagrant 1.9.5

ゲスト環境

OS CentOS 7.1.1503
Python 3.6.1
pip 9.0.1
Web フレームワーク Django 1.11.2
データベース MariaDB 5.5.52-1.el7.x86_64
Webサーバ nginx 1.13.2
uWSGI 2.0.15
Bootstrap bootstrap-4.0.0-alpha.6-dist
django-bootstrap-form 3.2.1

Vagrantへログイン

①【ホスト環境】端末を開き、前回構築したVagrantのディレクトリまで移動します。

cd vagrant/django_apps/

②【ホスト環境】仮想マシンを起動します。

vagrant up

③【ホスト環境】ログインします。

vagrant ssh

firewall停止

①デフォルトで用意されているindex.htmlにHTTPアクセスできるか確認するため、firewalldを停止状態にします。

sudo systemctl stop firewalld
sudo systemctl disable firawalld

pyvenvで作成した仮想環境にログイン

前回、pyenvで仮想環境「venv_app1」を作成しました。ここにログインします。

①【ホスト環境】Vagrantの中の「venv_app1」ディレクトリまで移動します。

cd /vagrant/django_apps/venv_app1/

②【ゲスト環境】「venv_app1」を有効化します。

source ./bin/activate

以下のようなプロンプトが表示されれば有効化成功です。

(venv_app1) [vagrant@localhost venv_app1]$ 

テンプレート作成

テンプレートは、「app1/templates/」ディレクトリ配下に配置します。

IPアドレスを管理するアプリケーションをつくります。以下のサイトを参考にさせていただきました。

Python3.4 + Djangoで作るWebアプリケーション(Part.2 アプリ開発編)

①templatesディレクトリを作成します。

mkdir pj1/app1/templates

②「ipaddress.html」を作成します。

vi pj1/app1/templates/ipaddress.html

以下のようなコードを記述します。

{% load staticfiles %}

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>App1</title>

    <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
    <link href="{% static 'css/bootstrap-reboot.min.css' %}" rel="stylesheet">
        <link href="{% static 'css/bootstrap-grid.min.css' %}" rel="stylesheet">
    <script src="{% static 'js/jquery-3.2.1.min.js' %}"></script>
    <script src="{% static 'js/bootstrap.min.js' %}"></script>
  </head>

  <body>
    <nav class="navbar navbar-toggleable-md navbar-inverse bg-inverse">
      <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <a class="navbar-brand" href="#">App1</a>
      <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav">
          <li class="nav-item active">
            <a class="nav-link" href="#">Ipaddress <span class="sr-only">(current)</span></a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">Function 2</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">Function 3</a>
          </li>
        </ul>
      </div>
    </nav>

    <div class="container">
      <h1>IP address</h1>
      <table class="table table-striped table-bordered">
        <thead>
          <tr>
            <th>IP address</th>
            <th>Status</th>
            <th>Description</th>
          </tr>
        </thead>
        <tbody>
          {% for ipaddress in ipaddresses %}
          <tr>
            <td>{{ ipaddress.ipaddress }}</td>
            <td>{{ ipaddress.status }}</td>
            <td>{{ ipaddress.description }}</td>
          </tr>
          {% endfor %}
        </tbody>
    </table>

    </div><!-- /.container -->

  </body>
</html>

Viewを定義

テンプレートを作成したら、データベースにあるIPアドレスの情報を表示させるアプリケーションを作ります。

①「pj1/app1/views.py」を以下のように修正します。

vi pj1/app1/views.py

変更前

from django.shortcuts import render

# Create your views here.

from django.http import HttpResponse


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

変更後

from django import forms
from django.forms import ModelForm
from .models import Ipaddress

class IpaddressForm(ModelForm):
    class Meta:
        model = Ipaddress
        fields = ('id', 'ipaddress', 'status', 'description')

    def __init__(self, *args, **kwargs):
        super(IpaddressForm, self).__init__(*args, **kwargs)
        for field_name, field in self.fields.items():
            field.widget.attrs['class'] = 'form-control'

②簡易Webサーバを立ち上げます。

python pj1/manage.py runserver 0.0.0.0:8000

③ホスト環境のブラウザから、以下のURLを入力します。

http://192.168.33.15:8000/app1/

以下のようなページが表示されます。

IPアドレス管理するViewを定義

アプリケーションにIPアドレス情報の変更機能を追加します。

①pj1/app1/urls.pyを下記のように編集します。

vi pj1/app1/urls.py

②新たに「http://192.168.33.15:8000/app1/change/1/」などのURLを定義します。また、データベース上のIPアドレス情報のプライマリIDが「ipaddress_id」に紐づくように指定しています。

vi pj1/app1/urls.py
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^change/(?P<ipaddress_id>\d+)/$', views.ipaddress_change, name='ipaddress_change'),
]

③ipaddressテーブルのフィールド情報の値を変更できるようにするため、「app1/forms.py」を作成します。forms.pyを作成すれば、HTMLテンプレートに{{ form }}と記述するだけで全フィールドを呼び出すことができます。

from django import forms
from django.forms import ModelForm
from .models import Ipaddress

class IpaddressForm(ModelForm):
    class Meta:
        model = Ipaddress
        fields = ('id', 'ipaddress', 'status', 'description')

④「app1/veiws.py」を以下のように追記します。

vi pj1/app1/views.py
from django.shortcuts import render
# Create your views here.

from django.http import HttpResponse
from django.shortcuts import get_object_or_404, redirect
from .models import Ipaddress
from .forms import IpaddressForm

def index(request):
    # データベース上のIPアドレス情報を配列型で取得
    ipaddresses = Ipaddress.objects.all().order_by('id')

    context = {'ipaddresses' : ipaddresses}

    return render(request, 'ipaddress.html', context)

def ipaddress_change(request, ipaddress_id=None):

    if ipaddress_id:
        ipaddress =  get_object_or_404(Ipaddress, pk=ipaddress_id)
    else:
        ipaddress = Ipaddress()

    if request.method == 'POST':
        # 基本的にPOSTが推奨される
        form = IpaddressForm(request.POST, instance=ipaddress)
        if form.is_valid():
            form = form.save(commit=False)
            form.save()
            return redirect('app1:ipaddress')
    else:
        # GETの場合はこちらを実行
        form = IpaddressForm(instance=ipaddress)

    return render(
       request,
       'ipaddress_change.html',
       dict(form=form, ipaddress_id=ipaddress_id)
    )

⑤テンプレートファイル「app1/template/ipaddress.html」に追記します。

vi pj1/app1/templates/ipaddress.html
{% load staticfiles %}

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>App1</title>

    <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
    <link href="{% static 'css/bootstrap-reboot.min.css' %}" rel="stylesheet">
    <link href="{% static 'css/bootstrap-grid.min.css' %}" rel="stylesheet">
    <script src="{% static 'js/jquery-3.2.1.min.js' %}"></script>
    <script src="{% static 'js/bootstrap.min.js' %}"></script>

    <style>
    .page_header {
        display: block;
        width: 100%;
        margin: 0.6em 0;
        padding: 0.6em 0;
        border-bottom:1px solid #eee;
    }
   </style>
  </head>

  <body>
    <nav class="navbar navbar-toggleable-md navbar-inverse bg-inverse">
      <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <a class="navbar-brand" href="#">App1</a>
      <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav">
          <li class="nav-item active">
            <a class="nav-link" href="#">Ipaddress <span class="sr-only">(current)</span></a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">Function 2</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">Function 3</a>
          </li>
        </ul>
      </div>
    </nav>

    <div class="container">
      <h1 class="page_header">IP address</h1>
      <table class="table table-striped table-bordered">
        <thead>
          <tr>
            <th>ID</th>
            <th>IP address</th>
            <th>Status</th>
            <th>Description</th>
            <th>Function</th>
          </tr>
        </thead>
        <tbody>
          {% for ipaddress in ipaddresses %}
          <tr>
            <td>{{ ipaddress.id }}</td>
            <td>{{ ipaddress.ipaddress }}</td>
            <td>{{ ipaddress.status }}</td>
            <td>{{ ipaddress.description }}</td>
            <td>
              <a href="{% url 'app1:ipaddress_change' ipaddress_id=ipaddress.id  %}" class="btn btn-primary">Change Status</a>
            </td>
         </tr>
         {% endfor %}
        </tbody>
    </table>

    </div><!-- /.container -->

  </body>
</html>

⑥変更機能のために新たにテンプレートファイル「app1/template/ipaddress_change.html」を作成します。

vi pj1/app1/templates/ipaddress_change.html
{% load staticfiles %}

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>App1</title>

    <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
    <link href="{% static 'css/bootstrap-reboot.min.css' %}" rel="stylesheet">
    <link href="{% static 'css/bootstrap-grid.min.css' %}" rel="stylesheet">
    <script src="{% static 'js/jquery-3.2.1.min.js' %}"></script>
    <script src="{% static 'js/bootstrap.min.js' %}"></script>

    <style>
    .page_header {
        display: block;
        width: 100%;
        margin: 0.6em 0;
        padding: 0.6em 0;
        border-bottom:1px solid #eee;
    }

    .btn_container {
        margin: 1em 0 0 -1em;
    }
   </style>
  </head>

  <body>
    <nav class="navbar navbar-toggleable-md navbar-inverse bg-inverse">
      <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <a class="navbar-brand" href="#">App1</a>
      <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav">
          <li class="nav-item active">
            <a class="nav-link" href="#">Ipaddress <span class="sr-only">(current)</span></a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">Function 2</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">Function 3</a>
          </li>
        </ul>
      </div>
    </nav>

    <div class="container">
      <h3 class="page_header">Change Status</h3>
      <form action="" method="post" class="form-group" role="form">
          {% csrf_token %}
          {{ form }}
          <div class="form-group">
            <div class="container btn_container">
                <button type="submit" class="btn btn-primary">Change Status</button>
                <a href="{% url 'app1:index' %}" class="btn btn-secondary">Back</a>
            </div>
          </div>
      </form>
    </div><!--/.nav-collapse -->

  </body>
</html>

以上のようにファイルを編集することで、「Change Status」ボタンをクリックしてIPアドレス情報を変更することができるアプリケーションが完成です。

⑦ホスト環境のブラウザから、以下のURLを入力します。

http://192.168.33.15:8000/app1/

以下のようなページが表示されます。


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

名前:イワサキ ユウタ 職業:システムエンジニア、ウェブマスター 誕生:1986年生まれ 出身:静岡県 特技:ウッドベース 略歴 2008年04月 金融機関系I

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