Django入門ノート その4

テンプレートの基本

あらかじめ作成しておいたひな型にデータを投入してHTML等の文字列をつくるテンプレートの基本について勉強です。

まずは単純にテンプレート用の文字列からテンプレートをつくるパターン。
テンプレート文字列をdjango.templateモジュールのTemplateクラスに渡してテンプレートオブジェクトを生成する。データの投入はdjango.templateモジュールのContextクラスでコンテキストオブジェクトを生成し、updateメソッドで内容を追加する。今回は辞書を渡します。 最後にテンプレートオブジェクトのrenderメソッドにコンテキストを渡して呼び出すと最終的な出力文字列が生成される。
test_template.py

#! /usr/bin/env python

from django.http import HttpResponse
from django.template import Template, Context

test_template_string = """
<html>
<body>
<table>
<tr><td>Key</td><td>Value</td></tr>
{% for item in dic.items %}
<tr>
<td>{{ item.0 }}</td><td>{{ item.1 }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
"""
def test_template(request):
    template = Template(test_template_string)
    dic = {"year":2011, "month":12, "day":29}
    context = Context()
    context.update({"dic":dic})
    return HttpResponse(template.render(context))

テンプレート文字列内の{{ ... }}や{% ... %}で囲まれた部分はDjangoのテンプレート言語で記述されたテンプレート命令というものとのこと。前者をテンプレート変数、後者をテンプレートタグ({% for ... %} ... {% endfor %}のようにセットになってるものはブロックタグ)と呼ぶとのこと。テンプレート変数は、出力時に変数の内容で置き換えられ、テンプレートタグはその場所でなんらかの操作を行って、その結果でタグが置き換えられる。今回は{% for ... %} ... {% endfor %}のブロックでループを組んでいる。タグの中ではメソッド呼び出しの()が不要なのも注意点。urls.pyで作成したビューをセットしてアクセスすると辞書dicのキーと値が一覧で表示される。

前の例だと特定のビューとテンプレートが結びついてしまうため実用的ではないので、テンプレートをファイルシステムからロードする方法を続いて勉強します。ファイルシステムからロードすることでページテンプレートの設計とビューの設計を分離することが可能になるとのこと。

まずはテンプレートファイルを入れるディレクトリを作成します。

$ mkdir templates

テンプレート用ディレクトリを作成したらsettings.pyのTEMPLATE_DIRSに絶対パスで登録しておく。
前の例のテンプレート文字列の内容をTEMPLATE_DIRS下のload_template_test.htmlに保存します。
テンプレートのロードにはdjango.templateモジュールのloderオブジェクトを使うとのこと。loderオブジェクトにはget_templateメソッドがあり、テンプレートのパスをTEMPLATE_DIRSからの相対パスで指定すると、テンプレートファイルを探し出してTemplateクラスに渡し、テンプレートオブジェクトを生成して返してくれる。
load_template.py

#! /usr/bin/env python

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

def load_template_test(request):
    dic = {"year":2011, "month":12, "day":29}
    context = Context()
    context.update({"dic":dic})
    template = loader.get_template('load_template_test.html')
    return HttpResponse(template.render(context))

urls.pyで作成したビューをセットしてアクセスすると先の例と同様に辞書dicのキーと値が一覧で表示される。

テンプレートは継承による再利用と拡張が可能とのことでやってみます。
まずは親テンプレートbase.htmlで{% block ... %}タグを使い子テンプレートでカスタマイズ可能なブロックを作成しておく。

base.html

<html>
  <head>
    <title>{{ title }}</title>
	{% block head_extra %}
	{% endblock %}
  </head>
  <body>
    {% block body %}
	  {{ content }}
    {% endblock %}
  </body>
</html>

一方の子テンプレートextend.htmlでは親テンプレートの名前を指定して{% extends ... %}を呼び出し、親テンプレートのブロックのうち、子テンプレートでカスタマイズしたい部分を{% block %}で定義する。これをブロックのオーバーライドと呼ぶとのこと。

extend.html

{% extends "base.html" %}
{% block head_extra %}
  <meta http-equiv="content-type: text/html; charset=UTF8" />
{% endblock %}
{% block body %}
  <h1>{{ title }}</h1>
  <hr />
  {{ content }}
  <hr />
{% endblock %}

子テンプレートを使用するビューを書いてみます。

extend_template_test.py

#! /usr/bin/env python

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

def extend_template(request):
    context = Context()
    dic = {'title':u'継承によるテンプレートの再利用と拡張', 'content':u'本文'}
    context.update(dic)
    template = loader.get_template('extend.html')
    return HttpResponse(template.render(context))

urls.pyで作成したビューをセットしてアクセスすると子テンプレートでオーバーライドしたブロックの内容が置き換わっている。

ちなみにテンプレートのブロックは何重でもネスト可能で、子テンプレートではどのレベルのブロックをオーバーライドしてもよいらしい。

Django入門ノート その3

ビューの基本

ユーザーから送られるリクエストに対して処理を行い、結果のコンテンツやレスポンスコードを返す役割をDjangoではビューというものが担っているらしい。
ビューはPythonの関数として定義すれば良くて第1引数にはリクエストオブジェクトを受け取る。
つまりDjangoサイトの特定のURLにアクセスがあったとき、そのURLに対応したコンテンツやレスポンスコードを返すビューが呼ばれるように設定すれば良いってことですね。
そしてURLとビューの対応はURLconf(urls.py)で設定すれば良いわけか。
ではテストのビューをプロジェクト直下に書いてみる。
test_view.py

#! /usr/bin/env python

from django.http import HttpResponse

def hello(request):
    message = "<html><body>Hello, Django!</body></html>"
    return HttpResponse(message)

def get_form_data(request):
    text1 = request.GET['text1']
    text2 = request.GET['text2']
    return HttpResponse('text1=%s, text2=%s' %(text1, text2))

importしているHttpResponseはコンテンツを伴う通常のHTTPレスポンスを表すクラスで、コンテンツを与えてレスポンスオブジェクトを生成すれば良いみたい。
ビューの引数で受け取るリクエストオブジェクトからはユーザーから送信される情報にアクセスできる。
GETメソッドで送信されたデータの取得の仕方もPHPなんかに慣れてるとわかりやすいですね。

次は書いたビューに対応するようにプロジェクトを作成したときにできたurls.pyを設定します。

from django.conf.urls.defaults import *
from test_view import *

# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()

urlpatterns = patterns('',
    # Example:
    # (r'^project/', include('project.foo.urls')),
      (r'^greet/$', hello),
      (r'^formdata/$', get_form_data),

    # Uncomment the admin/doc line below to enable admin documentation:
    # (r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    # (r'^admin/', include(admin.site.urls)),
)

定義したビューを参照できるようにimportしておいて、URLに対応する各ビューをタプルにして設定するんですね。
URLパターンには正規表現が使用できると。わかりやすいですね。

Django入門ノート その2

プロジェクトを立ち上げる

プロジェクトとはおおまかに言ってDjangoで動くWebサイトひとつを表し、django-admin.pyを使って作ることができる。
新しいプロジェクトを作るときはプロジェクトを作成するディレクトリで

$ django-admin.py startproject 作成するプロジェクト名

とすると実行したディレクトリにプロジェクト名のディレクトリができる。
プロジェクトディレクトリの中には__init__.py、manage.py、settings.py、urls.pyがあるので確認。

開発用サーバの起動

Django付属の開発用サーバを起動するときは

$ python manage.py runserver

としてブラウザでhttp://localhost:8000/にアクセスしてIt worked!の表示を確認

mod_pythonの設定

せっかくmod_pythonをインストールしたのに試さないのはもったいないので、以後は開発用サーバは使わずにApache上で動かすことにします。
Apacheの設定ファイルに今回は以下ような設定を追加。

	LoadModule python_module modules/mod_python.so

	<Location "/project/">
	    SetHandler python-program
		PythonHandler django.core.handlers.modpython
		SetEnv DJANGO_SETTINGS_MODULE project.settings
		PythonOption django.root /project
		PythonDebug On
		PythonPath "['/path/to/project'] + sys.path"
	</Location>

	<Location "/media">
	    SetHandler None
	</Location>

	<LocationMatch "\.(jpg|gif|png)$">
	    SetHandler None
	</LocationMatch>

Apacheを再起動したらブラウザでhttp://localhost/project/にアクセスしてIt worked!の表示を確認。

Django入門ノート その1

Pythonを始めていいかげん経ったのでDjangoでも勉強してみようかと思います。
「開発のプロが教える標準Django完全解説」を教科書代わりにやっていきます。
今回は下準備というか諸々のインストールをしていく。
プラットフォームはubuntuPythonubuntuに付属の2.5.2を使っていきます。

Django本体のインストール

公式サイトよりofficial versionのこの時点での最新版1.2.4をダウンロードして展開。

$ tar xzvf Django-1.2.4.tar.gz

展開されてできたDjango-1.2.4ディレクトリに移動してインストール。

$ sudo python setup.py install
データベース

MySQLを既にインストール済みだったのでMySQLを使うことにする。PythonからMySQLを扱うために MySQL-pythonをインストールする。

$ sudo easy_install MySQL-python

ってやったらmysql_configが無いってエラーになった。
調べてみるとlibmysqlclient15-devパッケージにあるらしいとのことなので、

$ sudo apt-get install libmysqlclient15-dev

をして再び

$ sudo easy_install MySQL-python

をしたところまたエラー!今度はこんなメッセージ。

Setup script exited with error: command 'gcc' failed with exit status 1

再び調べてみるとpython-devパッケージを入れれば良いらしいので、

$ sudo apt-get install python-dev

今度こそということで、

$ sudo easy_install MySQL-python

無事にインストール完了。
Djangoで使うデータベースとMySQLユーザを作っておく。

mysql> create database djangodb;
mysql> grant all on djangodb.* to xxxx@'localhost' identified by xxxx;
WebサーバとPythonインターフェイス

Apacheは既にインストール済みなのでmod_pythonをインストールする。

$ sudo apt-get install libapache2-mod-python

pythonにnoseを入れてみたときのメモ

pythonでのunittestを容易に実行できるライブラリということで評判が良さげなnoseを入れたときのメモ。

インストールはeasy_installで行った。

$ easy_install nose

テストの実行はnosetestsコマンドでテスト対象のファイルやディレクトリを指定するか、テストスクリプト内から実行することもできるらしい。

とりあえず試してみる。

nose_test.py

class TestNose(object):
    def test_nose(self):
        assert 1==1

def test_func():
    assert 1==1

if __name__=='__main__':
    import nose
    nose.main()

まずはファイルを指定して実行

$ nosetests nose_test.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK
$ nosetests -w test
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

テストスクリプトから実行

$ python nose_test.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

wordpressのパーマリンクの設定

インストールを終えたwordpressパーマリンクの設定を行ったときのメモ。

mod_rewriteの設定

apachemod_rewriteを有効にする。

$ sudo a2enmod rewrite

apacheの設定ファイルを編集してディレクティブの「AllowOverride None」
のNoneをAllに変更する。

$ sudo vi /etc/apache2/sites-available/default

apacheを再起動する。

$ sudo /etc/init.d/apache2 restart
.htaccessファイルの作成と書き込み権限の付与
$ sudo vi /var/www/wordpress/.htaccess
$ sudo chmod 646 /var/www/wordpress/.htaccess

wordpressのインストール

VMware Player上のubuntuwordpressをインストールしてみる。

ApacheMySQLPHPはインストール済みってところからスタート。

WordPressで使用するデータベースとユーザーをMySQLに作成する

設定内容は以下の通りとしてやってみる。

データベース名 : wordpressdb
ユーザー名     : wpadmin
パスワード     : password
ホスト名       : localhost

まずはMySQLに接続してデータベースを作成する

create database wordpressdb;

作成したデータベースを使用するユーザーを作成する

grant all on wordpressdb.* to 'wpadmin'@'localhost' 
identified by 'password';
wordpressのダウンロード

http://ja.wordpress.org/からwordpress-2.9.1-ja.zipをダウンロード

ファイルの配置

Apacheのドキュメントルートの直下(今回は/var/www/)にダウンロードしたファイルを展開して配置する

$ sudo unzip wordpress-2.9.1-ja.zip
インストール

ブラウザから「http://localhost/wordpress/」にアクセス

文字化けしていたらMySQLPHPで設定している文字コードwordpress文字コードと違っている。
wordpress文字コードUTF-8なのでMySQLPHP文字コードUTF-8に設定する。

「wp-config.php ファイルを作成する」をクリックしてウィザード形式でやってみる。

あらかじめ用意していたデータベース接続情報を入力する。

wp-config.phpへの書き込みができませんと出たので手動でファイルを作成してデータベース接続情報を編集することにする。

$ cd /var/www/wordpress/
$ sudo cp wp-config-sample.php wp-config.php
$ sudo vi wp-config.php

ブログのタイトル名とメールアドレスの初期値を入力してインストールをクリックする。
初期設定ユーザー名とパスワードをメモしてログインする。

メモしたユーザー名とパスワードを入力し、画面右下の「ログイン」と書かれたボタンをクリックする。

ブログの管理画面が表示されればインストールは完了。

今後管理画面へログインするには「http://localhost/wordpress/wp-login.php」へアクセスするとログイン画面が表示される。

http://localhost/wordpress/」へアクセスしてブログの表示を確認して終了。