1-7. TemplateViewでテンプレートを表示する

今回のテーマは「TemplateViewでテンプレートを表示する」です。テンプレートを表示するためにはViewに書いた関数でrenderを使えば良いことを紹介してきました。ここでもう1つの表示方法を紹介しておきます。 ※本ページは1-6. テンプレートの継承とincludeまで読まれた方を対象としています。そのためサンプルソースコードが省略されている場合があります。


関数のビューとクラスベースビュー

Djangoのビューの書き方は関数で書く場合とクラスベースビューというクラスを用いる方法があります。歴史的には関数によるビューが先で、オブジェクティブな拡張性をもとめてクラスベースのビューが登場したようです。(参考:クラスベースビュー入門

クラスベースビューには汎用的に用いられるものがDjango側で予め用意してあり、それらのクラスをオーバーライドして拡張して使うことが頻繁にあります。関数型のビューだけでなくクラスベースビューにも早いうちから慣れておくことが良いと思います。

TemplateViewを使ってみる

汎用的なクラスベースビューにはTemplateView, DetailView, ListViewなどがあり、より少ないコードで表示できるよう工夫してあります。今回はTemplateViewを使ってみます。TemplateViewはViewクラスをオーバライドしたテンプレートを表示するためのビュークラスです。現在のbase/views.pyを書き換えてみましょう。

base/views.py

from django.views.generic import TemplateView

class TopView(TemplateView):
    template_name = 'base/top.html'

    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        ctx['title'] = 'IT学習ちゃんねる(仮)'
        return ctx

base/urls.pyも作成したTopViewを使用するように書き換えます。

base/urls.py(一部抜粋)

urlpatterns = [
-    path('', views.top, name='top'
+    path('', views.TopView.as_view(), name='top'),
]

これだけでは何のメリットがあるのか分からないかも知れませんが、クラスベースビューは頻繁に使いますので覚えておいて損はないです。また、テンプレートにコンテキストを渡す際に、get_context_data関数をオーバーライドする方法もよく用います。(この他にも方法はあるのですが、今はこの方法だけ覚えておけばよいかと思います。) TemplateViewのもう少し便利な使い方を見ていきましょう。もしコンテキストをviews.pyから渡す必要がない場合はurls.pyのみで完結することも出来ます。単順にHMTLファイルを出力したいだけの場合はviews.pyからコンテキストを渡す必要はありません。今回は利用規約ページがそのようなページに相当する想定で実装してみます。 まずはテンプレートを用意します。

templates/base/terms.html

{% extends 'base/base.html' %}
{% block title %}利用規約 - {{ block.super }}{% endblock %}
{% block content %}

<div class="ui grid stackable">
  <div class="eleven wide column">
    <div class="ui breadcrumb">
      <a href="{% url 'base:top' %}" class="section">TOP</a>
      <i class="right angle icon divider"></i>
      <a class="active section">利用規約</a>
    </div>
    <div class="ui segment">
      <div class="content">
        <div class="header"><h3>利用規約</h3></div>
        <p>あんなことやこんなことを守って下さい。などなど</p>
        <p>...............</p>
        <p>...........</p>
        <p>.......</p>
      </div>
    </div>
  </div>
  {% include 'base/sidebar.html' %}
</div>
{% endblock %}

base/urls.pyは以下のように変更します。

base/urls.py

  from django.urls import path
+ from django.views.generic import TemplateView
  from . import views
  app_name = 'base'

  urlpatterns = [
      path('', views.top, name='top'),
+     path('terms/', TemplateView.as_view(template_name='base/terms.html'), name='terms'),
  ]

ブラウザで確認すると以下のようになります。

ここでbase/terms.htmlの中でリンク先の指定時に{% url ‘base:top’ %}を用いました。このように書くとbase/urls.pyでapp_nameで指定した’base’アプリケーション名の’top’のURLを自動的に挿入してくれます。便利なのでよく使います。また、views.pyの中でもリダイレクト時などに良く出てくる表現です。さて、本題ですが、これでテンプレートを表示するだけであればurls.pyだけで事足りることが分かりましたね。

最後に

TemplateViewの使い方いかがだったでしょうか?歴史的な経緯もあり、テンプレートを表示するだけでも色々な方法があります。最初は戸惑うかも知れませんが、だんだんと慣れていくと自分の好みの方法が見つかると思います。ここまでとても簡単ですがビューとテンプレートを扱ってきました。次回はMVTのMであるモデルを扱っていきます。

Sponsored Link


1-6. テンプレートの継承とinclude

今回のテーマは「テンプレートの継承とinclude」です。現時点でtemplate/base/top.htmlはフッダー、ヘッター、サイドバーとコンテンツを全て有する1つのHTMLファイルとして生成されました。しかし、ヘッダー、フッター、サイドバー等は他のページでも使い回すことが想定されるものです。また、ログインページにはサイドバーを出したくないなど、必要に応じて取り込んだり、外したりする部品もあります。このような要望に対してDjangoテンプレートは継承とインクルードという二つの方法でテンプレートを使い回す方法を提供しています。では、実際に見ていきましょう。 ※本ページはstaticファイルを扱うまで読まれた方を対象としています。そのためサンプルソースコードが省略されている場合があります。


テンプレートの継承

まず、templates/base/base.htmlを用意し、ここに全ページで共通して使う部品を配置します。他のページではこのbase.htmlを継承して変更部分のみをはめ込むことにします。base.htmlはこんな感じになります。

templates/base/base.html

{% load static %}
<!DOCTYPE html>
<head>
  <meta charset="UTF-8">
  <meta http-equiv="content-language" content="ja">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  {% block meta_tag %}{% endblock %}
  <link href="{% static 'css/semantic.css' %}" rel="stylesheet">
  {% block css %}{% endblock %}
  <title>
    {% block title %}IT学習ちゃんねる{% endblock %}
  </title>
</head>
<body>
  <div class="ui stackable inverted menu">
    <div class="header item">
      IT学習ちゃんねる
    </div>
    <a class="item">
      このサイトはなに?
    </a>
    <div class="right menu">
      <a class="item">
        Log in
      </a>
      <a class="item">
        Sign up
      </a>
    </div>
  </div>
  
  <div class="ui container" style="min-height:100vh;">
    {% block content %}
    {% endblock %}
  </div>
  <div class="ui inverted stackable footer segment">
    <div class="ui container center aligned">
      <div class="ui horizontal inverted small divided link list">
        <a class="item">© 2019 Django学習ちゃんねる(仮)</a>
        <a class="item">利用規約</a>
        <a class="item">プライバシーポリシー</a>
      </div>
    </div>
  </div>
  <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
  <script type="text/javascript" src="{% static 'js/semantic.js' %}"></script>
  {% block js %}{% endblock %}
</body>

{% block hogehoge %}{% endblock %}で囲まれた部分の中身をbase.htmlを継承した各テンプレートファイルで作成していきます。templates/base/top.htmlは次のように変更されました。

templates/base/top.html

{% extends 'base/base.html' %}
{% block title %}ITについて切磋琢磨する掲示板 - {{ block.super }}{% endblock %}
{% block content %}
<div class="ui grid stackable">
  <div class="eleven wide column">
    <div class="ui breadcrumb">
      <a class="section">TOP</a>
      <i class="right angle icon divider"></i>
      <a class="section">category</a>
      <i class="right angle icon divider"></i>
      <div class="active section">thread</div>
    </div>
    <div class="ui segment">
      <div class="content">
        <div class="header"><h3>新着スレッド</h3></div>
        <div class="ui divided items">
          <div class="item">
            <div class="content">
              <div class="header">
                <a><h4>dummy thread</h4></a>
              </div>
              <div class="meta">
                <span class="name">投稿者名</span>
                <span class="date">2019-2-1 00:00</span>
              </div>
            </div>
          </div>
          <div class="item">
            <div class="content">
              <div class="header">
                <a><h4>dummy thread</h4></a>
              </div>
              <div class="meta">
                <span class="name">投稿者名</span>
                <span class="date">2019-2-1 00:00</span>
              </div>
            </div>
          </div>
          <div class="item">
            <div class="content">
              <div class="header">
                <a><h4>dummy thread</h4></a>
              </div>
              <div class="meta">
                <span class="name">投稿者名</span>
                <span class="date">2019-2-1 00:00</span>
              </div>
            </div>
          </div>
          <div class="item">
            <div class="content">
              <div class="header">
                <a><h4>dummy thread</h4></a>
              </div>
              <div class="meta">
                <span class="name">投稿者名</span>
                <span class="date">2019-2-1 00:00</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
{% endblock %}

この場合は{% block content %}の中身をtop.htmlで作ってはめ込んでいるんですね。尚、今回{% block meta_tag %}や{% block css %}, {% block js %}等を用意したのはページによって特殊に加えたいMETAタグやCSS,JSが出てくることを想定しているためです。またページタイトルに関しては常にbase.htmlのタイトルをハイフンつなぎで表示する目的でblock.superを使ってbase.htmlのタイトルを呼び出しています。

テンプレートのインクルード

今度はサイドバーも別パート化してみましょう。templates/base/sidebar.htmlとします。

templates/base/sidebar.html

<div class="five wide column">
  <div class="ui action input" style="width: 100%;">
    <input type="text" placeholder="検索">
    <button class="ui button"><i class="search icon"></i></button>
  </div>
  <div class="ui segment">
    <div class="content">
      <div class="header"><h4>話題のトピック</h4></div>
      <div class="ui relaxed list small divided link">
        <a class="item">dummy</a>
        <a class="item">dummy</a>
        <a class="item">dummy</a>
        <a class="item">dummy</a>
        <a class="item">dummy</a>
      </div>
    </div>
  </div>
</div>

これをtop.htmlの下から2行目に追加して読み込んでみましょう。top.htmlを修正します。

templates/base/top.html

   </div>
+  {% include 'base/sidebar.html' %}
 </div>

そうですね。部分的に作ったsidebar.htmlをインクルードするだけです。これで必要な場合のみインクルードすれば使えるように別部品化できました。 見た目に関してはstaticファイルを扱うから変化していません。ただしテンプレートが部品化されたことでより効率的な開発が出来ると思います。

最後に

Djangoのテンプレートにはまだ便利な機能がたくさんありますが、機能を使う際に紹介していければと考えています。クラスベースビューを使ってテンプレートを表示する方法を見ていきたいと思います。

Sponsored Link


1-5. staticファイルを扱う

今回のテーマは「staticファイルを扱う」です。ここまででテンプレートファイルをviews.pyで表示することができるようになりました。今度はCSSやJavascript、image等のstaticなファイルを読み込めるようにしましょう。 ※本ページはビューとテンプレートの基礎まで読まれた方を対象としています。そのためサンプルソースコードが省略されている場合があります。


Staticファイルの置き場所

まずはプロジェクト直下にstaticディレクトリを作成します。templateと同じ階層になります。

(venv)$ mkdir -p static

図示すると以下ような感じです。

mysite
││└mysite
│└─base
└──static

ここではstatic以下にcss,jsディレクトリを作成します。

(venv)$ cd static
(venv)$ mkdir -p css
(venv)$ mkdir -p js

今回はSimantec UIのcssとjsを導入してみます。今回はlassによるカスタマイズ等はしませんのでダウンロードページからzipファイルをダウンロードしてsemantic.cssとsemantic.jsをそれぞれ先程作成した各ディレクトリに設置します。 ただし、この状態ではまだファイルを読み込むことが出来ません。Djangoにどこにstaticファイルがあるのかを教える必要があります。そこでmysite/settings.pyに設定を追加します。

mysite/settings.py

import os # もしインポートしていない場合


STATIC_URL = '/static/'

+ STATICFILES_DIRS = [
+     os.path.join(BASE_DIR, 'static'),
+ ]

Django 4.0でsettings.pyを作成した場合にはosモジュールがインポートされていない可能性があるので、osモジュールをインポートしてください。

CSSを適用したトップページのテンプレート

これでstaticディレクトリをDjangoが認識しました。では先程のCSSとJSをテンプレートに読み込んでみましょう。 template/base/top.htmlは以下のようにします。

template/base/top.html

{% load static %}
<!DOCTYPE html>
<head>
  <meta charset="UTF-8">
  <meta http-equiv="content-language" content="ja">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

  <link href="{% static 'css/semantic.css' %}" rel="stylesheet">
  <title>{{title}}</title>
</head>
<body>
  <div class="ui stackable inverted menu">
    <div class="header item">
      {{title}}
    </div>
    <a class="item">
      このサイトはなに?
    </a>
    <div class="right menu">
      <a class="item">
        Log in
      </a>
      <a class="item">
        Sign up
      </a>
    </div>
  </div>
  
  <div class="ui container" style="min-height:100vh;">
    <div class="ui grid stackable">
      <div class="eleven wide column">
        <div class="ui breadcrumb">
          <a class="section">TOP</a>
          <i class="right angle icon divider"></i>
          <a class="section">category</a>
          <i class="right angle icon divider"></i>
          <div class="active section">thread</div>
        </div>
        <div class="ui segment">
          <div class="content">
            <div class="header"><h3>新着スレッド</h3></div>
            <div class="ui divided items">
              <div class="item">
                <div class="content">
                  <div class="header">
                    <a><h4>dummy thread</h4></a>
                  </div>
                  <div class="meta">
                    <span class="name">投稿者名</span>
                    <span class="date">2019-2-1 00:00</span>
                  </div>
                </div>
              </div>
              <div class="item">
                <div class="content">
                  <div class="header">
                    <a><h4>dummy thread</h4></a>
                  </div>
                  <div class="meta">
                    <span class="name">投稿者名</span>
                    <span class="date">2019-2-1 00:00</span>
                  </div>
                </div>
              </div>
              <div class="item">
                <div class="content">
                  <div class="header">
                    <a><h4>dummy thread</h4></a>
                  </div>
                  <div class="meta">
                    <span class="name">投稿者名</span>
                    <span class="date">2019-2-1 00:00</span>
                  </div>
                </div>
              </div>
              <div class="item">
                <div class="content">
                  <div class="header">
                    <a><h4>dummy thread</h4></a>
                  </div>
                  <div class="meta">
                    <span class="name">投稿者名</span>
                    <span class="date">2019-2-1 00:00</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
       </div>
      <div class="five wide column">
        <div class="ui action input" style="width: 100%;">
          <input type="text" placeholder="検索">
          <button class="ui button"><i class="search icon"></i></button>
        </div>
        <div class="ui segment">
          <div class="content">
            <div class="header"><h4>カテゴリー</h4></div>
            <div class="ui relaxed list small divided link">
              <a class="item">dummy</a>
              <a class="item">dummy</a>
              <a class="item">dummy</a>
              <a class="item">dummy</a>
              <a class="item">dummy</a>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div class="ui inverted stackable footer segment">
    <div class="ui container center aligned">
      <div class="ui horizontal inverted small divided link list">
        <a class="item">© 2019 IT学習ちゃんねる(仮)</a>
        <a class="item">利用規約</a>
        <a class="item">プライバシーポリシー</a>
      </div>
    </div>
  </div>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="{% static 'js/semantic.js' %}"></script>
</body>

まだ仮のフロントなので仮組みの状態です。キーポイントはファイルの一番最初で行っている{% load static %}です。これによって以降staticをテンプレートで使えるようになります。そしてCSS,JSを読み込む箇所では{% static ‘js/semantic.js’ %}のようにしてファイルを読み込みます。 ブラウザで確認すると下図のように見えるはずです。

Djangoテンプレートは多くのウェブフレームワークのテンプレート同様に条件分岐、繰り返し、フィルター等の機能が使えます。その際には{% %}の間に記述をします。コンテキストでViewから与えられた変数を適用する{{}}と混同しないように注意してくださいね。

最後に

これでCSS、JSがDjangoのテンプレートで読み込めるようになりました。フロントエンドで出来ることも大きく増えると思います。次回はよりテンプレートを効率的に使用する方法を見ていきましょう。 【関連記事】 4-3. DjangoのStaticファイルの扱い

Sponsored Link


1-4. ビューとテンプレートの基礎

今回のテーマは「ビューとテンプレートの基礎」です。今までは細々と設定作業ばかりでDjangoの面白さを実感出来なかったかも知れません。いよいよ特定のURLに対してHTMLを出力していきますよ。

※本ページはアプリケーションの作成まで読まれた方を対象としています。そのためサンプルソースコードが省略されている場合があります。


Djangoにおけるビューとテンプレート

DjangoはMVT(Model, View, Template)モデルのフレームワークを自称しています。よく知られているMVCモデルとよく似ていますが、MVCモデルにおけるViewが「情報をどのように見せるのか?」という観点で作られるのに対して、DjangoにおけるViewは「表示すべき情報は何か?」を用意しテンプレートに渡す役割を果たしています。「どのように見せるか?」という出力についてはテンプレートが担います。即ちViewはユーザーのアクションに応じてビジネスロジックを担うモデルに通知し、ユーザーに見せる情報を受け取りテンプレートに渡す仕事をします。詳細は公式ドキュメントを参照下さい。

Hello World

とにかく文字を画面に出しましょう。

base/views.py

from django.http import HttpResponse
from django.template import loader

def top(request):
    return HttpResponse('Hello World')

このviews.pyに追加したtop関数をURLと結びつけるためbase/urls.pyを修正します。

base/urls.py

from django.urls import path
from . import views
app_name = 'base'

urlpatterns = [
    path('', views.top, name='top'),
]

ではブラウザで見てみましょう。

(venv)$ ./manage runserver 0.0.0.0:8080

ブラウザでlocalhost:8080にアクセスします。Hello Worldが出ましたね。

templatesディレクトリを設定する

テンプレートを使いたいのですが、まずはテンプレートをどこに配置するか決定しましょう。Djangoのデフォルト設定では各アプリケーション内のtemplatesディレクトリから探す設定となっています。 図にすると

mysite
│└app1
│  └templates
│    └app1
│      └template.html
│
└app2
  └templates
    └app2
      └template.html

というイメージです。一方、テンプレートファイルを1つのtemplatesディレクトリで管理する方法もあります。その場合は

mysites
 └templates
   │└app1
   │ └template.html
   └─app2
      └template.html
  ...

となります。ディレクトリ構成は好みもありますし、プロジェクトの方針にもよりますが、筆者は後者が好みです。前者の構成はアプリケーションがテンプレートを含んだモジュールとして独立することが念頭にあります。今回は後者の設定で進めます。もし前者のスタイルとする場合は以下の設定は不要です。 mysites/settings.pyのTEMPLATES部分の設定を書き換えます。

+ import os #インポートされていない場合はインポートする

- 'DIRS': [],
+ 'DIRS': [os.path.join(BASE_DIR, 'templates')],

templatesディレクトリをプロジェクト直下に作成し、その中にbaseディレクトリを生成しましょう。

(venv)$ cd mysite #プロジェクト直下にいない場合は移動する
(venv)$ mkdir -p mysite/templates/base

テンプレートを使ってみる

baseアプリケーション用のテンプレートファイルを生成します。

mysite/templates/base/top.html

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="content-language" content="ja">
    <title>{{title}}</title>
</head>
<body>
<h1>{{title}}</h1>
<p>テンプレートテスト表示</p>
</body>

テンプレートを使用するようにbase/views.pyのtop関数も以下のように書き直します。

base/views.py

from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader

def top(request):
    template = loader.get_template('base/top.html')
    ctx = {'title': 'Django学習ちゃんねる(仮)'}
    return HttpResponse(template.render(ctx, request))

ではブラウザで確認してみましょう。

(venv)$ ./manage runserver 0.0.0.0:8080

ちなみに毎回runserverを実行することはなく、実行したままソースを書き換えて保存すると自動的に反映されます。(一部settingsに関わるものなどは反映されませんので再起動が必要)

なんとも恥ずかしいタイトルですがスルーしてください。views.pyで渡したtitleパラメータがテンプレートに渡されていることが確認されました。Djangoテンプレートはdict型の変数でパラメータを渡し、テンプレート側では「{{}}」でパラメータ名を囲うことで表示されます。 さて、表示されましたが、テンプレートに表示する度に先程のようにテンプレートを読み込んで表示するのは面倒なのでショートカットが用意されています。先程のviews.pyは以下のように書き換え出来ます。

base/views.py

from django.shortcuts import render
# from django.http import HttpResponse
# from django.template import loader

def top(request):
    # template = loader.get_template('base/top.html')
    ctx = {'title': 'Django学習ちゃんねる(仮)'}
    # return HttpResponse(template.render(ctx, request))
    return render(request, 'base/top.html', ctx)    

loaderもHttpResponseも不要になりスッキリ書けますね。renderを使用すると任意のテンプレートにコンテキスト(テンプレートに変数を渡す入れ物と考えて下さい)を渡して表示することが出来ます。

最後に

現段階ではHTMLを出力するだけでCSSやjavascript等のファイルは読み込んでいません。モダンなWEBアプリにCSS,JSは必須(もはや主役)ですので配置方法を見ていくことにします。

Sponsored Link


1-3. アプリケーションの作成

今回のテーマは「アプリケーションの作成」です。Djangoではプロジェクトの中にアプリケーションという単位のユニットを組み合わせて1つのWEBアプリケーションを作り上げていきます。アプリケーションの作成は何度も行う作業ですので慣れてしまいましょう。 ※本ページはデータベースへの接続準備まで読まれた方を対象としています。そのためサンプルソースコードが省略されている場合があります。


Djangoにおけるアプリケーション

設計に正解はありませんが、Djangoは独立性のある小さなアプリケーションを組み合わせることで1つのWEBアプリケーションを構築することが推奨される風潮があります。この辺りのことはDjango Best Practiceを参考にしてください。独立したアプリケーションを集積するメリットは他のWEBアプリを開発する時に移植性が高い設計ができるという利点があります。どの単位でアプリケーションを区切るかというのは難しい問題ですが、他の機能との相互作用がない独立した機能の場合は1つのアプリケーションとして分けて汎用性の高い設計をしておくと、繰り返す使えるモジュールとして使えるようになります。 Djangoアプリケーションはモデルを有したモジュールであり、配布することも可能です。他のWEBアプリで用いていたアプリケーションをインポートするだけで、そっくり機能を移植することができれば理想的な設計だと思います。 ただ、現実的な問題としてテンプレートが絡む場合には単順な移植が困難なことも多いです。多くのテンプレートはWEBアプリ固有のものが多く、多層構造で依存性が高いためです。残念ながら筆者も抽象度が高く汎用性の高い設計を目指して奮闘中の身であり、多くは語れません。本ブログでも設計が拙い部分は多々あると思いますが、お気づきの点はご指摘、ご指導いただけると幸甚です。

アプリケーションを生成する

今回は掲示板アプリを作成するため"base"という名前のアプリケーションを追加します。このbaseアプリケーションはWEBアプリの基盤としてトップページや利用規約、プライバシーポリシーといった基本的な構成を機能させるためのアプリケーションとなります。 ※baseアプリケーションは利用規約等の静的なページ(TOPページは除く)の表示をまとめて行うアプリケーションですが、必ずしもこのようなアプリケーションが必要なわけではありません。また、このようなベースアプリケーションを作成するとファットになり勝ちで嫌われるケースもあります。ケースバイケースで設計しましょう。

$ source venv/bin/activate
(venv)$ cd mysite
(venv)$ ./manage startapp base

これでbaseアプリケーションが生成されました。

アプリケーションを組み込む

生成したアプリケーションを使用するためにプロジェクトに組み込みます。 settings.pyに追記します

settings.py

 INSTALLED_APPS = [
     'django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.staticfiles',
+    'base',
 ]

アプリケーションのURL設定

生成したbaseディレクトリ内に新規ファイルurls.pyを生成しましょう。中身はこうなります。

base/urls.py

from django.urls import path

name = 'base'

urlpatterns = []

一方でmysiteディレクトリ内のurls.pyにも追記します。

urls.py

- from django.urls import path
+ from django.urls import path, include
+ import base


 urlpatterns = [
     path('admin/', admin.site.urls),
+    path('', include('base.urls'))
 ]

これはドメイン直下の部分(http://my.domain.com/ココの部分)がbaseアプリケーションのurls.pyに直結されたことを意味します。この意味は追々分かってくると思います。

最後に

ここまでがアプリケーションの生成と追加でした。次回はこのbaseアプリケーションにビューとテンプレートを追加してDjangoにおける表示について学習します。

Sponsored Link


1-2. データベースへの接続準備

今回のテーマは「データベース接続準備」です。DjangoのデータベースはデフォルトではSQLiteです。もしSQLiteを使う想定の場合は本記事の内容は飛ばして結構です。WEBアプリケーションでよく使われるであろうMariaDBもしくはPostgreSQLに接続するための設定について見ていきます。

※本ページはプロジェクトの作成まで読まれた方を対象としています。そのためサンプルソースコードが省略されている場合があります。


データベースの準備

まずデータベースの準備をします。プロジェクト用のユーザー(postgresqlの場合はROLE)とデータベースを作成します。今回はlocalhostのDBにアクセスする想定で進めます。異なるホストのDBを使用する場合は適宜読み替えて下さい。

MariaDBの場合

mysql -u root -p{password}

{password}にはrootパスワードを入れて下さい。

[MariaDB] CREATE DATABASE forum_data;
[MariaDB] CREATE USER "forum_user"@"localhost" IDENTIFIED BY "{password}";
[MariaDB] GRANT ALL ON forum_data.* TO 'forum_user'@'localhost';

{password}にはMariaDBのrootユーザーパスワードを入れて下さい。

Postgresqlの場合

$ su postgres
#パスワード入力
postgres$ psql postgres

postgresql内で操作します。

 [postgres] CREATE ROLE forum_user WITH LOGIN CERATEDB PASSWORD '{password}';
 [postgres] \connect - forum_user #ユーザーの切り替え
 [postgres] CREATE DATABASE forum_data;

標準では認証方式がpeerとなっているためパスワードでログイン出来るようにpg_hba.confファイルを変更します。場所はディストリビューションやバージョンによって異なるので一概に言えないのですが、RedHat系は/usr/local/pgsql/data/以下、Debian系は/etc/{バージョン}/main/以下が多いと思います。Macは…RedHat系と同様だったと思いますが記憶が曖昧です。

pg_hba.conf

- local   all         all          peer
+ local   all         postgres     peer
+ local   all         all          md5

これでpostgresユーザーのみpeerで他のユーザーはパスワードでログイン可能となりました。 データベースの細かい設定は今回の目的から逸れるので細かく触れません。ご自分の環境に合わせて作成して下さい。尚、ご存知の通りPostgresqlはデフォルト設定でlocalhostからのみアクセス可能な設定となっていますので、外部からアクセスする際は設定を変更して下さい。(postgres.confにて設定)

データベースドライバのインストール

MariaDBの場合

(venv)$ pip install mysqlclient

Postgresqlの場合

(venv)$ pip install psycopg2-binary

データベース接続の設定

settigs.pyに以下例のように記述します。

settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'forum_data',
        'USER': 'forum_user',
        'HOST': 'localhost',
        'PASSWORD': '{##your password##}',
    }
}

「{##your password##}」の部分はデータベースのパスワードを設定して下さい。Postgresqlの場合はENGINEが’django.db.backends.postgresql’となるだけです。

最後に

これでデータベースに接続する準備が整いました。この後マイグレーションを行い、Django標準のモデルを基にデータベーステーブルを作成するのが一般的ですが、マイグレーションについては別の機会に扱うこととします。

Sponsored Link


1-1. プロジェクトの作成

今回のテーマは「プロジェクトの生成」です。Djangoでは1つのWEBアプリをプロジェクトという単位で管理します。プロジェクトの生成とブラウザでの確認について見ていきましょう。


プロジェクトの生成

まずはプロジェクトを生成しましょう。Djangoプロジェクトはすぐに生成できます。

$ source venv/bin/activate
(venv)$ django-admin createproject myproject

生成されたmysiteプロジェクトのディレクトリ構成は以下のようになります。


.
├── manage.py
└── mysite
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

言語設定を行う

生成されたばかりのプロジェクトの言語設定は英語ですので、これを日本語にしましょう。myprojectディレクトリのsettings.pyファイルを編集します。

settings.py

- LANG='en_us'
+ LANG='ja'

ウェブブラウザで確認する

これでmyprojectディレクトリが作成されました。では作成したプロジェクトをウェブブラウザで確認してみましょう。DjangoにはプロジェクトをすぐにWebブラウザで確認できるようにバルクサーバーがついています。これはあくまで開発用ですので、決して本番環境では動作させないでくださいね。

(venv)$ cd myproject
(venv)$ python manage.py runserver 8080

もし8080ポートを他の用途に使用してる場合は8000等、お好みのポートに変更して下さい。では、ウェブブラウザでlocalhost:8080にアクセスして確認してみましょう。図のようなロケットの絵が出ていればOKです。

プロジェクト作成画面

次回は…

次回はデータベースとの接続です。一歩ずつ頑張りましょう!

Sponsored Link


0-2. Django開発環境を整える

今回のテーマは「Django開発環境を整える」です。筆者の環境はLinuxですので、Linuxがベースの記事となりますが、Pythonが動く環境であれば大きな変化はないと思いますので適宜読み替えて下さい。ではまずDjangoを使える環境を整えましょう。


python仮想環境の準備

ここでは、Djangoで開発を進めていく際の準備をしていきます。まずpythonですが、3系での利用を想定しています。もし、python2.xしか入っていない状況でしたら3系をインストールして下さい。

次にvenvにて開発用に仮想環境を作ります。本サイトでは基本的にvenv環境で操作をしていきます。

$ python3 -m venv venv

ディストリビューションによってはpython3へのリンクがpythonだったりpython3だったりと異なりますのでご注意下さい。venvディレクトリが作成されているはずです。コマンドの2つめの’venv’は別のフレーズでもOKです。その場合は指定したフレーズのディレクトリが生成されます。では、作ったvenv環境を有効化しましょう。

$ source venv/bin/activate

これでvenv環境が有効化されました。

蛇足ですが、以下のコマンドでvenv環境から出ることができます。

(venv)$ deactivate

Djangoのインストール

ではDjangoをインストールして行きましょう。venv環境のpipを用いるだけなので何も難しいことはありません。

(venv)$ pip install django

これで準備が整いました。

最後に

次回はDjangoプロジェクトを生成してWebブラウザで確認する作業をしていきます。
本記事がお役に立てば幸いです。

Sponsored Link


0-1. はじめに

Django学習帳とは?

このサイト迷い込んだということはDjangoというフレームワークに多少なりとも興味を持たれてご覧になっているのだろうと思います。このサイトは網羅的な辞書やDjangoの仕組みを丁寧に解説するガイドブックではありません。それらのサイトは世に優れたものがあり筆者のようなものが手を出すには恐れ多い領域です。このサイトではひたすら手を動かし、自らの手でサイトを作り上げることで機能を会得していくスタイルを目指します。語学学習で言うならば文法が頭に入っていない状態でいきなり留学するような感覚です。実践をこなすことで体系的なDjangoの使い方が身に付くのではないかと考えています。


Django学習帳の使い方

初心者の方は必ず自分の手を動かして作業をしながら読んで下さい。基本的には最初から順を追って進んでいくことを前提としています。よって途中からスポット的に読むとサンプルコードに省略があり分かりづらい点があるかも知れません。(毎ページに全コードを載せられないので)Djangoを使ったことがあり、その欠損を自力で補える方は飛ばし飛ばし読んでも大丈夫かも知れません。

何故このサイトを作ろうと思ったか

DjangoでWebサイトを作ろうと思った時、公式ドキュメントを始めネット上にある様々な情報の断片にアクセスしそれを自分なりに消化していく作業が大変でした。たしかに公式ドキュメントはまとまった情報量があるのですが、欲しい情報にアクセスするまでに時間が掛かりもどかしかった記憶があります。このサイトは自分がDjangoを使い始めた時に「こんなサイトがあったら良かったな」という情報をまとめたつもりです。

ところでDjangoとは?

このサイトを開いている皆さんに説明するまでもないことは承知しているのですが、簡単に説明するとDjangoはpythonで作られたフルスタックWebフレームワークです。RubyだとRuby on RailsとかPHPだとLaravelやCakePHPのようなフレームワークを思い浮かべれば良いかと思います。テンプレートからルーター、ORM(Object relational mapper)までWeb開発で必要となる機能を一通り揃え、さらには便利なプラグインの開発も行われています。Webの技術は進化・変化が凄まじく早く、DjangoのようなWEBフレームワークがいつまで表舞台にいられるかは見通しが立ちませんが、それでも学んで見る価値はあるフレームワークだと思っています。

このサイトの対象者

Django学習帳はこれからDjangoを使ってみたい方を対象としました。業務でバリバリ使っている方がレベルアップの目的で読むととても物足りないと思います。Djangoのソースコードを読んでる方がためになります。

テーマ毎にミニサンプルを作成する方法も考えましたが、プロジェクトの生成からWEBアプリを完成させるというストーリーを体験することで得られるものがあると考えストーリーの中に要素技術を織り込みました。

どんなモノを作るのか

Django学習帳では実際にサイトを作りながら学習を進めて行きます。定番ですが、掲示板サイトを作りながらDjangoの基礎的な部分、便利な機能を習得するスタイルにしたいと考えています。学習の都合で無理な構成になっている部分のもありますが、致命的な点はご指摘いただければと思います。

Sponsored Link