Djangoの基本チュートリアル

  • 1月 19, 2009 23:11

今回は、Djangoをインストールしたばかりの人を想定した、簡単なDjangoの説明をしたいと思います。

今回はWindowsで行います。

コマンドプロンプトを立ち上げて、プロジェクトを作りたいディレクトリに移動します。

今回は、C:/tmp/django_firstというディレクトリで行いますが、好きなディレクトリで行ってください。

まず「firstproject」というプロジェクトを django-admin.py startproject firstproject で作ります。

django-admin.pyはdjangoのインストール先のdjango/binにあります。windowsの場合は以下の場所にあると思います。

C:/tmp/django_first>python c:/Python25/Lib/site-packages/django/bin/django-admin.py startproject firstproject

#firstprojectのディレクトリに移動して中身を確認します


C:/tmp/django_first/firstproject>dir
ドライブ C のボリューム ラベルがありません。
ボリューム シリアル番号は 30E0-5C63 です

C:/tmp/django_first/firstproject のディレクトリ

2009/01/19  23:31    <DIR>          .
2009/01/19  23:31    <DIR>          ..
2009/01/19  23:31             2,864 settings.py
2009/01/19  23:31                 0 __init__.py
2009/01/19  23:31               557 manage.py
2009/01/19  23:31               566 urls.py

と、このように4つのファイルができました。

  • settings.py 設定ファイル
  • manage.py django-admin.pyの代わりにテストサーバーを動かしたり、モデルからDBのテーブルを作ったりテストを動かしたりいろいろします。
  • urls.py アクセスされたURLを実際の処理に振り分ける
  • __init__.py ディレクトリ構造をPythonのパッケージにするためのファイル

では、ここでテストサーバーを動かしてみましょう

It worked

という画面が表示されればOKです。しかし、この時点では何もできないのでコマンドプロンプトから

「Ctrl + c」キーを同時押しをして終了させましょう。

つぎにアプリを作ります。Djangoはプロジェクトの中に複数のアプリを作ることができます。

アプリを作るのは

C:/tmp/django_first/firstproject>python manage.py startapp firstapp

# できたファイルの中身を確認する

C:/tmp/django_first/firstproject>dir firstapp

C:/tmp/django_first/firstproject/firstapp のディレクトリ

2009/01/19  23:54    <DIR>          .
2009/01/19  23:54    <DIR>          ..
2009/01/19  23:54                60 models.py
2009/01/19  23:54                 0 __init__.py
2009/01/19  23:54                27 views.py
               3 個のファイル                  87 バイト
               2 個のディレクトリ  75,211,472,896 バイトの空き領域

と、アプリの雛形である

  • models.py モデルを作るところ
  • views.py 表示する部分を作るところ
  • __init__.py ディレクトリ構造をPythonのパッケージとして認識させるために必要

ができました。

プロジェクトにfirstappをアプリとして認識させるためにfirstproject/settings.pyの編集をします。

INSTALLED_APPSにfirstproject.firstappを追加すればOKです。

#firstapp/settings.py
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    # 以下を追加
    'firstproject.firstapp',
)

さて、このプロジェクトfirstprojectとアプリで、いろいろ表示をしていこうかと思うのですが、まずはHelloWorldの表示からやってみたいと思います。

http://localhost:8001/ でアクセスされたときに「Hello World」と表示するものです。

まずはurls.pyの編集です。

#firstproject/urls.py

from django.conf.urls.defaults import *
urlpatterns = patterns('',
     (r'^$', 'firstproject.firstapp.views.helloworld'),
)

これはhttp://localhost:8001/でアクセスされたときにfirstapp/views.py の helloworld関数に表示処理を任せるという意味です。

では firstproject/firstapp/views.pyにhelloworld関数を作ってみましょう。

from django.http import HttpResponse

def helloworld(request):
    return HttpResponse("Hello World")

urls.pyから処理を任される関数はviews関数といって2つ決まりがあります。

  • 第一引数にdjango.http.HttpRequestオブジェクトのrequestをとる
  • django.http.HttpResponseオブジェクトをreturnする

HttpResponse生成の一番簡単は方法は文字列を引数に渡すことなので、これで

C:/tmp/django_first/firstproject>python manage.py runserver 0.0.0.0:8001

でテストサーバーを動かして、ブラウザでhttp://localhost:8001/にアクセスするとブラウザに

Hello World

と表示されたと思います。

これで一応表示までできましたが、HttpResponse("<html><head>~~~")のようにhtmlを書くわけにはいかないので、Djangoではテンプレートというものを作ります。

http://localhost:8001/ut/

とアクセスされたら、テンプレートを使った表示を返すようにしてみようと思います。

まずはfirstproject/urls.pyから

urlpatterns = patterns('',
     (r'^$', 'firstproject.firstapp.views.helloworld'),
     (r'^ut/$', 'firstproject.firstapp.views.usetemplate'), #ここを追加。
)

ulrs.pyから渡す関数名はusetemplateという名前にしました。さっそくfirstproject/firstapp/views.pyに追加しましょう。

from django.http import HttpResponse
from django.shortcuts import render_to_response #追加

def helloworld(request):
    return HttpResponse("Hello World")

def usetemplate(request): #以下追加
    retrun render_to_response('ut.html',
        {
            "hensu1": "HENSU1",
            "hensu2": "HENSU2"
        }
    )

テンプレートを使うにはいろいろ方法があるのですが、django.shortcuts.render_to_responseが良く使われます。これは第一引数にtemplateの名前を入れて、第二引数に{変数名:値}といった辞書を渡すことでHttpResponseオブジェクトを作ります。

今回はut.htmlという名前のテンプレートを作ることにしました。これをどこに置いたらいいかというと、settings.pyのTEMPLATE_DIRSに置く場所を設定することもできますが、djnagoはアプリの下に「templates」というディレクトリがあったら、そのディレクトリにテンプレートがあるか自動的に探してくれます。

なので、今回はfirstproject/firstapp/templates/ut.htmlというファイルを作りましょう。

C:/tmp/django_first/firstproject>mkdir firstapp/templates

をしてから、今回は簡単ですが以下のようなut.htmlを作ってみました。

<html>
       <head>
               <title>First Django</title>
       </head>
       <body>
               {{ hensu1 }} <br />
               {{ hensu2 }} <br />
       </body>

</html>

さきほどのviews関数でhensu1とhensu2という名前の辞書を作りましたので、その値「HENSU1」「HENSU2」が表示されればOKです。

うまく表示されたでしょうか??

ではこのまま、このテンプレートを使ってリストなどのシーケンシャル(連続した)なオブジェクトや、値が辞書のものを扱ってみたいと思います。

firstproject/firstapp/views.py

from django.http import HttpResponse
from django.shortcuts import render_to_response

def helloworld(request):
    return HttpResponse("Hello World")

def usetemplate(request):
    return render_to_response('ut.html',
        {
           "hensu1": "Hensu1",
           "hensu2": "Hensu2",
           "lis": ["spam", "ham", "egg"], #追加
           "dic": {"name": "value"}, #追加
        }
    )

これらを扱うfirstproject/firstapp/templates/ut.htmlを以下のように追加しました。

<html>
       <head>
               <title>First Django</title>
       </head>
       <body>
               {{ hensu1 }} <br />
               {{ hensu2 }} <br />
               <p>
               LIST
               <ul>
               {% for i in lis %}
                     <li>{{ i }} </li>
               {% endfor %}
               </ul>
               </p>
               <p>
               Dictonary<br />
               dic["name"] = {{ dic.name }}
               </p>
       </body>
</html>

これで、リストや辞書がつかるようになったと思います

(後で図を入れる)

{% -- %}がテンプレートの関数的なものを扱い

{{ -- }} が値を表示する

と思ってもらえればOKです。

そして辞書のdic["name"]をあらわすのは {[ dic.name }} だということにも注目してください。

さて、次はクラスです。

firstproject/firstapp/views.pyを以下のように変更しました。Personというクラスを作ってpeopleという名前の値にPersonで作ったインスタンスのリストを入れました。

from django.shortcuts import render_to_response

class Person(object):

    def __init__(self, name, age):
        self.name = name
        self.age = age

def helloworld(request):
    return HttpResponse("Hello World")

def usetemplate(request):
    return render_to_response('ut.html',
        {
           "hensu1": "Hensu1",
           "hensu2": "Hensu2",
           "lis": ["spam", "ham", "egg"],
           "dic": {"name": "value"}
           "people": [
               Person("John", 34),
               Person("Paul", 33),
           ]
        }
    )

対するテンプレートは以下のようにしました。

firstproject/firstapp/templates/ut.html

<html>
       <head>
               <title>First Django</title>
       </head>
       <body>
               {{ hensu1 }} <br />
               {{ hensu2 }} <br />
               <p>
               LIST
               <ul>
               {% for i in lis %}
                     <li>{{ i }} </li>
               {% endfor %}
               </ul>
               </p>
               <p>
               Dictonary<br />
               dic["name"] = {{ dic.name }}
               </p>
               <p>
               class
               <ul>
               {% for person in people %}
                    <li>Name: {{ person.name }} Age: {{ person.age }}</li>
               {% endfor %}
               </ul>
               </p>
       </body>
</html>

こちらは {{ person.name }} と {{ person.age }} とそのままですね。

これで表示されたと思います(あとで図)

さて、次はurlsについてもう少し説明を加えたいと思います。

Webアプリは、アクセスされるURLそのものを使って処理を分けたいときがあります。

たとえばBLOGなどでは

http://localhost:8001/blog/2008/12/24/

などでアクセスすると 2008年12月24日のエントリーを表示するように設計することなどがあるでしょう。

このチュートリアルでBLOGを扱うのは大変なので、

http://localhost:8001/plus/33/44/

をすると33 + 44 の結果 77 を返すようなサンプルを作りましょう。

まず、firstproject/urls.py

from django.conf.urls.defaults import *

urlpatterns = patterns('',
     (r'^$', 'firstproject.firstapp.views.helloworld'),
     (r'^ut/$', 'firstproject.firstapp.views.usetemplate'),
     (r'^plus/(?P<arg1>\d+)/(?P<arg2>\d+)/$', 'firstproject.firstapp.views.calc', #追加
         {"templatename":"calc.html"}),
)

さて、この(?P<arg1>¥d+) はpythonの名前つき正規表現の書き方です。これで括弧ないのパターン(この場合は数値)にマッチしたものにarg1という変数に入れてくれます。

なので、

http://localhost:8001/plus/33/44/

の場合、arg1=33, arg2=44 というように切り出しをします。そしてDjangoは続くviews関数(firstproject/firstapp/views.py)の引数に名前付き引数として渡します。

そして、タプルの3つ目の {"templatename":"calc.html"} という辞書も、templatename="calc.html"という名前付き引数としてviews関数に渡します。

firstproject/firstapp/views.py は

from django.http import HttpResponse, Http404
from django.shortcuts import render_to_response

#途中省略
def calc(request, arg1, arg2, templatename='calc.html'):
    try:
        arg1 = int(arg1)
        arg2 = int(arg2)
    except:
        raise Http404
    result = arg1 + arg2
    return render_to_response(templatename,
           {
               "arg1": arg1,
               "arg2": arg2,
               "result": result
           }
    )

とします、views関数の決まりは * 第一引数にHttpRequestオブジェクトのrequestをとる * HttpResponseオブジェクトをreturnする のが決まりなので、

calc関数の第一引数にrequest、

そして、続く引数はurls.pyから渡された、arg1, arg2, templatenameになります。

注意点は、整数として正規表現でマッチしたarg1, arg2ともに文字列として渡されている点です。

なのでtry構文の中で int(arg1), int(arg2) と型のキャストを行っています。さらにここでエラーが起きた場合は404エラーを返す raise Http404を発生させています。

そして、firstproject/firstapp/templates/calc.htmlです

<html>
    <title>CALC</title>
    <body>
           {{ arg1 }} + {{ arg2 }} = {{ result }}
    </body>
</html>

これは、もう説明するまでもないですね。

(図をいれる)

次にurlの逆引きです。

<明日、また続き>

次はテンプレートの敬称です。

<あとで書く>

さて、最後はmodelとformです。