Archive@2007/06

UbuntuをEdgy EftからFeisty Fawnへ

やっとこさ重い腰を上げて Ubuntu のアップグレードやったよ。

Python 2.5がデフォルトで入る事を忘れてて、ちょっとしたアクシデント発生。サーバをリブートしたら、 mod_python でエラー吐きまくる。エラーログを確認すると、どうやらパッケージで入った方を探しに行ってるみたい。(ログ取り忘れ。)

ココであがいても後々エライ目にあいそうだったので、どうせならって事でパッケージ側に新しく入れ直す事に。

まずは aptitudepython2.5-dev とか入ってるか確認。入ってなければ入れる。

$ sudo aptitude install python2.5-dev

次に mod_python とか。

$ wget http://www.meisei-u.ac.jp/mirror/apache/dist/httpd/modpython/mod_python-3.3.1.tgz
$ mv ./mod_python-3.3.1.tgz /usr/local/src
$ cd /usr/local/src
$ tar zxf ./mod_python-3.3.1.tgz
$ cd ./mod_python-3.3.1
$ ./configure \
> --with-apxs=/usr/local/httpd/bin/apxs \
> --with-python=/usr/bin/python2.5
$ make
$ sudo make install

次、 setuptoolsaptitude で探したら見つかったものの、バージョンが分からなかったので今回は自前で入れた。

$ wget http://cheeseshop.python.org/packages/2.5/s/setuptools/setuptools-0.6c6-py2.5.egg
$ mv ./setuptools-0.6c6-py2.5.egg /usr/local/src
$ cd /usr/local/src
$ sudo /bin/bash ./setuptools-0.6c6-py2.5.egg

後は easy_install で必要なパッケージを入れていく。 pysqlite 2.3.4 と Django は ソース落として来て setup.py 叩いて入れた。

これでひとまず元通り。良かった良かった。しかも、このアクシデントついでに mod_proxy な環境にしてみた。これからちょっとずつ実験していこうと思う。

Posted at: 
2007/06/30 15:37:41
2 Comments
0 TrackBacks
Tags: 
mod_python
Python
Ubuntu
Trackback: 
http://humming.via-kitchen.com/2007/06/30/upgrade-ubuntu-feisty-fawn/trackback/

フォームから送信した値とrequest.POSTの挙動($_POST@PHPとの比較)

LinuxなWEBデザイナーの覚書き。コチラ のエントリーより。

これ、自分も Django 使い始めた時に結構ハマった記憶があるなぁ。って事で、自分のためにメモ。

テンプレートはこんな感じ。(パクリ)

<form action="." method="post">
    <input type="checkbox" name="text" value="hoge" checked="checked" />
    <input type="checkbox" name="text" value="hage" checked="checked" />
    <input type="checkbox" name="text" value="mage" checked="checked" />

    <input type="submit" value="submit" />
</form>

test な名前の値を全部取る場合なら、

l = request.POST.getlist('test')

でどうでしょう? オリジナルのデータを弄らないようにするなら、

l = request.POST.copy().getlist('test')

の方が良いと思う。

PHP$_POST みたいな感じで最後のモノだけ取りたい場合は、

l = request.POST.copy().getlist('test')
l.reverse()
l = l[0]

とかになるのかな?ちょっと苦しいかも。もっとキレイな書き方があるかも知れない。

以下追記

uemura さんよりツッコミを頂きました。ありがとうございます!

QueryDict は受け取った順番を保持していて、普通に抜き取ると最後のものを返してくれるそう。って事で実験してみた。

l = request.POST['test']

return HttpResponse(l, mimetype='text/plain; charset=utf-8')

おお!ちゃんと mage って返ってきてる。なるほど。って事は以下でも可。

l = request.POST.copy().get('test')

return HttpResponse(l, mimetype='text/plain; charset=utf-8')

うむ。出来た出来た。

また一つ勉強になりました!

Posted at: 
2007/06/27 23:47:54
4 Comments
0 TrackBacks
Tags: 
Django
Python
Trackback: 
http://humming.via-kitchen.com/2007/06/27/comparison-between-django-and-php-of-request-post/trackback/

DjangoでTODOリストを作ろう(その4)

TODOリスト の4回目。

今回は駆け足で登録・更新・削除を作っていく。 コレが出来れば一通り必要な機能は全部実装。

ではでは早速。まずは urls.py を編集してリクエストからのパスを通してあげる。以下、 todo/urls.py

from django.conf.urls.defaults import *

# create, update, deleteを追加。
urlpatterns = patterns('',
    (r'^create/$', 'hige.todo.views.create'),
    (r'^update/(?P<object_id>\d+)/$', 'hige.todo.views.update'),
    (r'^delete/(?P<object_id>\d+)/$', 'hige.todo.views.delete'),
    (r'^list/$', 'hige.todo.views.list'),
    (r'^$', 'hige.todo.views.list'),
)

ココで出て来た (?P<object_id>\d+) って部分、 ココではURLから値を抜き取って、 object_id な名前をつけて view の引数に渡すよ。って指示をしてる。なので、 views.pyupdatedelete の引数には request 以外にも object_id な引数が飛び込んでくる。ココでは \d+ を指定してるので、数字しか一致しない。なので、引数に入ってくるのは必ず数字になる。(型が数字かどうかは別)

ちょっと眺めてみると hige.todo.views な文字が何回も書かれてる事に気づく。少しココで整頓しておく。 patterns 関数の第1引数はキックする view のプリフィックスを指定しておける便利機能付き。今回は hige.todo.views までが同じなので、それをプリフィックスとして指定する。

from django.conf.urls.defaults import *

# create, update, deleteを追加。
urlpatterns = patterns('hige.todo.views',
    (r'^create/$', 'create'),
    (r'^update/(?P<object_id>\d+)/$', 'update'),
    (r'^delete/(?P<object_id>\d+)/$', 'delete'),
    (r'^list/$', 'list'),
    (r'^$', 'list'),
)

コレでそれぞれリクエストから view までの紐付けが出来たので、 views.py に実装して行く。とりあえずは create から作って新規登録を出来るようにする訳ですが、殆ど変わらないので update も一緒に作ってしまう。以下、 todo/views.py

def create(request):
    p = {}

    # モデルに紐づくフォームのクラス!の作成
    f = forms.form_for_model(Task)

    # ココでフォームをインスタンス化
    form = f(request.POST.copy() or None)

    # データのバリデート処理
    if form.is_valid():

        # エラーが無ければセーブしてリダイレクト
        form.save()
        return HttpResponseRedirect('/todo/')

    # GETで来た時やエラーがあった場合はフォーム画面へ
    p['title'] = 'add new task.'
    p['form'] = form
    return render_to_response('todo/task_form.html', p)


def update(request, object_id):
    p = {}

    # object_idで該当するデータをもってくる。
    object = get_object_or_404(Task, pk=object_id, is_active=True)

    # インスタンスに紐づくフォームクラスの作成。
    f = forms.form_for_instance(object)

    form = f(request.POST.copy() or None)

    if form.is_valid():
        form.save()
        return HttpResponseRedirect('/todo/')

    p['title'] = 'update task #%s' % object.id
    p['form'] = form
    return render_to_response('todo/task_form.html', p)

ここでちょっと説明とか。バリデートに関しては、デフォルトでモデルを作成したときの制約をほぼそのままフォームに適応してくれる。ので、特に変更が無ければ何も書かなくてもちゃんとデータの妥当性を検証してくれる。 oldforms の頃からそうだったけど、 newforms になってさらにコード量が減った。かなり素敵。

で、ロジックで createupdate で違う所と言えば、既存のデータを取ってくるのと、それに合わせて newforms のメソッドが変わるぐらい。それ以外はほぼ一緒。テンプレートに落とすタイトルが違うぐらい。

次に todo/task_form.html を作る。 newforms には簡単にフォームを作る便利機能があるのですが、個人的にあんまり好きじゃないので、今回はひとつずつ書いていく。覚えといて損はないしね。

{% extends "base.html" %}

{% block title %}{{ title }}{% endblock %}

{% block contents %}
<h1>{{ title }}</h1>
<form action="." method="post" accept-charset="utf-8">
    <ul>
        <li>
            <label for="{{ form.priority.auto_id }}">
                {{ form.priority.label }}
            </label>
            {{ form.priority }}
            {% if form.priority.errors %}
            <label for="{{ form.priority.auto_id }}">
                {{ form.priority.errors|join:"," }}
            </label>
            {% endif %}
        </li>
        <li>
            <label for="{{ form.description.auto_id }}">
                {{ form.description.label }}
            </label>
            {{ form.description }}
            {% if form.description.errors %}
            <label for="{{ form.description.auto_id }}">
                {{ form.description.errors|join:"," }}
            </label>
            {% endif %}
        </li>
        <li>
            <label>&nbsp;</label>
            <input type="submit" value="add task." />
        </li>
    </ul>
</form>
{% endblock %}

コレでひとまず完了。ただ、このままだとURL直叩きじゃないと来れないので、一覧画面にテキトーにリンクを貼る。今回はあんまり深く考えずに create へのリンクは一番下あたりに、 update へのリンクは task 部分に貼ってみた。ついでに delete へのリンクもこしらえておく。以下、 task_list.html の抜粋。

{% block contents %}
<h1>Todo List</h1>
{% if object_list %}
<ul>
    {% for object in object_list %}
    <li>
        {{ object.priority }}&nbsp;
        <a href="/todo/update/{{ object.id }}/">{{ object }}</a>
        <a href="/todo/delete/{{ object.id }}/">delete</a>
    </li>
    {% endfor %}
</ul>
{% else %}
<p>no task.</p>
{% endif %}
<a href="/todo/create/">add new task.</a>
{% endblock %}

ココでひとまず遊んでみる。エラーな画面が出る場合はデバッグを楽しむ。一通り遊んでみたら最後に残った削除画面の作成にはいる。

削除機能に関しては、リンクから GET で飛んでだけでデータが削除されるってのは個人的にものすごく気持ち悪いので、確認画面を間に挟んでそこから POST させて削除する形で作る。以下、 views.py の抜粋。

def delete(request, object_id):
    p = {}
    object = get_object_or_404(Task, pk=object_id, is_active=True)

    # POSTなリクエストが来たら削除。
    if request.method == 'POST':
        object.delete()
        return HttpResponseRedirect('/todo/')

    p['object'] = object
    return render_to_response('todo/task_confirm_delete.html', p)

確認画面の todo/task_confirm_delete.html はこんな感じ。キャンセルボタンはちょっと手抜きしました。

{% extends "base.html" %}

{% block title %}delete confirm{% endblock %}

{% block contents %}
<p>delete task #{{ object.id }}?</p>
<dl>
    <dt>Priority:</dt>
    <dd>{{ object.priority }}</dd>
    <dt>Description:</dt>
    <dd>{{ object }}</dd>
</dl>
<form action="." method="post" accept-charset="utf-8">
    <input type="hidden" name="object_id" value="{{ object.id }}" />
    <input type="submit" value="delete this task." />
    <input type="button" value="cancel" onClick="javascript:history.back();" />
</form>
{% endblock %}

フォームから object_id な値を投げてるのは特に意味はありません。ただ、何も投げないのが気持ち悪かったのと、どっかで使えるかな?って思ってただけ。 POST で来た時にURL中の object_id と比較して、一致したら削除するってのも良いかも。(あんまり意味ないか?)

以下、今回のまとめ?

  • urls.pypatterns 関数の第1引数を上手く使おう。
  • URLからは正規表現でパラメータを引っこ抜く。
  • newforms はそのうち名前が変わるのでリネームは絶対。

これで一通りの動作を全部実装!かなり過不足が多い気がするけど。あと、デザインを全く弄ってないので見てくれはかなりダサイ。そこらへんは好みとかあると思うのであえて触れない方向で。

最後に Django の開発環境でのCSSなどの静的ファイルの提供方法を。プロジェクト直下の urls.py に以下を追加する。

from django.conf import settings
if settings.DEBUG:
    urlpatterns += patterns('django.views.static',
        (r'^site_media/(?P<path>.*)$', 'serve', {'document_root':settings.MEDIA_ROOT,}),
    )

HTMLにはこんな感じで書く。

<link rel="stylesheet" type="text/css" href="/site_media/path/to/css" />

コレでCSSとかJavaScriptとかも読み込めるはず。でも、コレはあくまでも開発環境用なので本番では使わないでね。とのこと。 コチラ本家サイト の情報が和訳されております。

結局 jQuery 使わなかった。すいません。でも、また時間見つけてなにか書きたいと思う。何より自分の勉強になりました。乱雑な内容ではありますが、これから Django を触ってみようと思ってる方(某 endless 氏とか)の手助けになればと思います。ってならないかぁ。

Posted at: 
2007/06/24 23:58:42
3 Comments
0 TrackBacks
Tags: 
Django
Python
Trackback: 
http://humming.via-kitchen.com/2007/06/24/todo-list-by-using-django-part4/trackback/

はじめてのPython買ったよ。

「Python クックブック 第2版」 を買いに渋谷まで。

が、立ち読みしてみたら内容に全然ついて行けなかったよ。とほほ。なので 「初めてのPython 第2版」 を買って帰りました。まだまだ Python への理解が乏しいので、熟読してちゃんと理解したいと思います。かなり楽しみ。

とりあえずは何気なく書いてるシェルとかを Python でやってみたりしてみようかな。

頑張れ!俺!

Posted at: 
2007/06/24 18:29:42
4 Comments
0 TrackBacks
Tags: 
book
Python
Trackback: 
http://humming.via-kitchen.com/2007/06/24/bought-learning-python/trackback/

DjangoでTODOリストを作ろう(その3)

またまた TODOリスト の続き。

やっとこさリクエストのルーティングとかテンプレートとか。今回は汎用ビューは使わずに、出来るだけベタで書いていこうと思う。

ではさっそく、下ごしらえから。まずはプロジェクトディレクトリにある urls.py を編集する。

from django.conf.urls.defaults import *

# ^todo/の行を追加。
urlpatterns = patterns('',
    (r'^todo/', include('hige.todo.urls')),
    (r'^admin/', include('django.contrib.admin.urls')),
)

これでリクエストURIが /todo/ で始まるものが来たら、 todo なアプリケーションの中にある urls.py を見るようになる。が、 todo なアプリケーションの中を見ても、 urls.py なんて無い。のでコピペとかして作ってしまう。

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^list/$', 'hige.todo.views.list'),
    (r'^$', 'hige.todo.views.list'),
)

とりあえずこんな感じ。現状だと /todo//todo/list/ なリクエストが来たら、 todo/views.pylist な関数をキックするようにしてある。

ココから views.py の編集。今回は Django - 0.96から使えるようになった newforms を使ってみたいと思う。コレは近々 forms に名前が変わるので読み込む段階でリネームしておく。

# Create your views here.

from django.http import Http404, HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render_to_response
from django import newforms as forms
from hige.todo.models import Priority, Task


def list(request):
    p = {}
    p['object_list'] = Task.objects.filter(is_active=True)
    return render_to_response('todo/task_list.html', p)

ココで書いた list な関数が /todo//todo/list/ なリクエストが来た時に実際にキックされる事になる。最後の render_to_response でブラウザに返すレスポンスをレンダリングしておしまい。

次に render_to_response の引数で指定している todo/task_list.html を作る。テンプレートの置き場所は settings.pyTEMPLATE_DIRS で指定した場所で、そこを基準として相対的なパスを Django が探してくれる。ので、今回は templates/todo なディレクトリの中に task_list.html を作る。これから何枚かテンプレートを作る事になるので、この段階でテンプレートの継承元も作ってしまっておく。

$ cd /path/to/hige/templates
$ touch base.html # コレが継承元になる。
$ mkdir todo
$ cd ./todo
$ touch task_list.html

まずは継承元の base.html から。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>{% block title %}Untitled{% endblock %}</title>
    </head>
    <body>
        {% block contents %}hello world.{% endblock %}
    </body>
</html>

次に task_list.html の作成。

{% extends "base.html" %}

{% block title %}todo list{% endblock %}

{% block contents %}
<h1>Todo List</h1>
{% if object_list %}
<ul>
    {% for object in object_list %}
    <li>{{ object.priority }}&nbsp;{{ object }}</li>
    {% endfor %}
</ul>
{% else %}
<p>no task.</p>
{% endif %}
{% endblock %}

このテンプレートの継承について。まずは1行目の extends タグで継承元を指定。で、後は親が持っている block タグを必要な所だけ上書きして行く形になっている。何枚でもネストして継承させれるので、 base.html で大枠を作っておいて todo/base.htmltodo アプリ共通部分を書いて todo/task_list.html でメインコンテンツを作成。って事も全然可能っす。親が持ってる隙間に対して穴埋め形式で必要な所を埋めて行く感じ。

これで runserver して http://localhost:8000/todo/ にアクセスすると今作ったTODOリストの一覧画面が出てくるはず。って言っても、まだ何も登録してないので no task. な文字が出るだけなのですが。

管理画面から登録・削除等を行うとちゃんと反映されるので、何か登録して動きを確認してみる。

以下、今回のまとめ?

  • urls.py はアプリケーション毎に用意出来る。(脱カップリング)
  • views.py 等の import はある意味暗記ものかも。
  • テンプレートの継承は慣れてくるとかなり便利。
Posted at: 
2007/06/23 22:36:06
0 Comments
0 TrackBacks
Tags: 
Django
Python
Trackback: 
http://humming.via-kitchen.com/2007/06/23/todo-list-by-using-django-part3/trackback/

DjangoでTODOリストを作ろう(その2)

TODOリスト の続き。

今回はアプリケーション作成からモデル作成ぐらいまで。

ではさっそく前回作ったプロジェクトの中にアプリケーションを作る。アプリケーション名はTODOリストなので todo とかにする。

$ ./manage.py startapp todo
$ ls -al ./todo
   0 Jun 20 02:48 __init__.py
  57 Jun 20 02:48 models.py
  26 Jun 20 02:48 views.py

出来たアプリケーションの中身はディレクトリの中に3枚のファイルだけ。 Django のポリシー的に「使うかどうか分かんないものは作らない。」らしい?こういうところ、個人的には好き。いつ使うのか分からないファイル群に翻弄されることがないからね。

このタイミングで settings.pyINSTALLED_APPS に、今作った todo なアプリを登録しておく。これをやっておかないと Django が見向きもしてくれない。

# 一番下にでも追加する。
INSTALLED_APPS = (
    ...,
    'hige.todo',
)

次はモデルの作成に入る。今回はテーブル1個で済ませてしまおうかと思ったものの、

JOIN とかどうやるんだよ!?」

な声が聞こえそうなので2個使ってやってみる。1つ目は todo の内容を保存するテーブル。もう1つは優先度を定義するテーブル。どうってことはないものの、まぁ楽しさは結構上がると思う。

ではさっそくアプリケーション作った時に出来た models.py を編集していく。

from django.db import models

# 日付を扱うのでインポート
import datetime

# 優先度のテーブル(モデル)
class Priority(models.Model):
    label = models.CharField(maxlength=20)

    class Meta:
        pass

    class Admin:
        pass

    def __str__(self):
        return self.label


# Todoの内容のテーブル(モデル)
class Task(models.Model):
    priority    = models.ForeignKey(Priority)
    description = models.CharField(maxlength=100)
    created_at  = models.DateTimeField(editable=False)
    updated_at  = models.DateTimeField(editable=False)
    is_active   = models.BooleanField(editable=False, default=True)

    class Meta:
        pass

    class Admin:
        pass

    def __str__(self):
        return self.description

    def save(self):
        current = datetime.datetime.now()
        self.updated_at = current
        if self.id is None:
            self.created_at = current
        super(Task, self).save()

    def delete(self):
        self.is_active = False
        self.save()

ココでちょっとした説明。カラム定義の部分は見たままなので大丈夫だと思う。 editableFalse にするとフォームに関連づけされなくなる。ので、ブラウザ越しで直には触れなくなる。

Task に関しては登録日時( created_at )と更新日時( updated_at )、論理削除フラグ( is_active )を持たせてみた。要らないかな?と思ったものの、ここらへんは某endless氏に対応。で、登録日時、更新日時を自動で入れる為に save をオーバーライドして、 idNone なら新規登録なので登録日時も入れるようにしてある。あとは論理削除をさせる為に delete をオーバーライド。

__str__ は他の言語で言う toString で、 Django の中で頻繁に呼び出されるメソッドなので定義しておいた方が良い。表側を作る時にも結構便利だし。このほかにも get_absolute_url ってのもあって、そのオブジェクトに対してユニークになるURLを返すためのメソッドとして使われる。今回は要らないかな?って事で作ってない。必要になったらその時作ろうと思う。

で、ここで作ったモデルをデータベースに反映させる為に syncdb を叩く訳ですが、 Priority には最初からデータが入っててほしいので、自動で流し込むようにひと工夫。アプリケーション直下に sql なディレクトリを作っておいて、 model_name.db_engine.sql なファイルを作っておくと Django が自動で食べてくれる。汎用性のあるSQLなら model_name.sql でも大丈夫。今回は初期データだけなので priority.sql にして作っておく。

$ cd ./todo
$ mkdir sql
$ cd sql
$ touch priority.sql

中身はインサート文をベタで書いておく。出来上がるテーブル名にはアプリケーション名のプリフィックスが自動で付くので、それを考慮しておく。

INSERT INTO todo_priority (label) VALUES ('Low'),('Mid'),('High');

あとは syncdb を叩いてデータベースに反映する。

$ ./manage.py syncdb
Creating table todo_priority
Creating table todo_task
Installing custom SQL for todo.Priority model
Installing index for todo.Task model
Loading 'initial_data' fixtures...
No fixtures found.

最後の No fixtures found なメッセージはエラーでは無いので気にしない。 Installing custom SQL for todo.Priority model なメッセージがあればちゃんとさっきのSQLをロードしてくれているはず。

以下、今回のまとめ?

  • Django は絶対必要なもの以外は作らない。
  • モデルが持つ __str__get_absolute_url は特別なメソッド。
  • アプリケーション直下の sql なディレクトリは意味深。
  • モデル定義のもっと詳しい情報は コチラ とか 本家情報 で。

今回も進まないまま時間だけが過ぎてった。次回はテンプレートとか触れたら良いなぁ。汎用ビュー使おうかどうか迷う。

Posted at: 
2007/06/21 00:17:06
4 Comments
0 TrackBacks
Tags: 
Django
Python
Trackback: 
http://humming.via-kitchen.com/2007/06/21/todo-list-by-using-django-part2/trackback/

DjangoでTODOリストを作ろう(その1)

Django に興味を持ってくれた職場仲間の為にTODOリストの作り方メモとか。

手練の方からのツッコミとかもお待ちしております!

始める前に今回は以下を使用。(某 endless 氏対応)

ではでは早速プロジェクト作りから。テキトーなディレクトリに移動してプロジェクトを作る。こういう時って名前に一番迷う。が、 test って名前のプロジェクトは通らないから気をつけて。

$ django-admin.py startproject hige

これでカレントディレクトリに hige なプロジェクトが出来てるはず。これからの作業はこの中で行う。中身は多分こんな感じ。

$ cd ./hige
$ ls -al
   204 Jun 19 00:05 ./
   306 Jun 19 00:05 ../
     0 Jun 19 00:05 __init__.py
   546 Jun 19 00:05 manage.py
  2800 Jun 19 00:05 settings.py
   221 Jun 19 00:05 urls.py

で、これからのシェルでの操作は manage.py を使って行う訳ですが、頻繁に使う manage.py にこの段階で実行属性を付けておく。

$ chmod +x manage.py

ここでとりあえず Django についてる開発サーバを立ち上げてみる。

# localhost:8000で立ち上がる。
$ ./manage.py runserver

# localhost:5000にしたい時。
$ ./manage.py runserver 5000

# 192.168.0.100:3000とかならコチラ。
$ ./manage.py runserver 192.168.0.100:3000

ブラウザからアクセスしてみて、 It worked! な画面が拝めたらいい感じ。ってかミスる所無いか。

次に今回使うデータベースを作ってしまう。 Django が文字コードを utf-8 で扱うので、データベースもそれに合わせておく。トラブらないようにね。

$ mysql -e 'CREATE DATABASE hige DEFAULT CHARSET utf8'

必要なら Django からデータベースへアクセスするためのユーザも作っておく。

ココから settings.py の編集に入る。データベースの設定とか、もろもろ基本的な設定を済ませてしまう。以下抜粋。

# ファイルの先頭あたりで追加
import os
BASE_PATH = os.path.abspath(os.path.split(__file__)[0])

# 14行目あたり
DATABASE_ENGINE = 'mysql'
DATABASE_NAME = 'hige'
DATABASE_USER = 'django'
DATABASE_PASSWORD = 'django'

# 26行目あたり
TIME_ZONE = 'Asia/Tokyo'

# 31行目あたり
LANGUAGE_CODE = 'ja_JP'

# 41行目あたり
MEDIA_ROOT = os.path.join(BASE_PATH, 'media')

# 45行目あたり
MEDIA_URL = '/site_media'

# 71行目あたり
TEMPLATE_DIRS = (
    os.path.join(BASE_PATH, 'templates'),
)

# 78行目あたり
# django.contrib.adminを追加。
INSTALLED_APPS = (
    ...
    'django.contrib.admin',
)

ココでちょいと説明。 BASE_PATH にはこのファイル( settings.py )までの絶対パスが入ってる。で、 MEDIA_ROOT , TEMPLATE_DIRS にはそれぞれプロジェクト直下の media なディレクトリ、 templates なディレクトリを指定してるっす。なので先にコレを作っておく。

$ mkdir media
$ mkdir templates

これで settings.py はとりあえず一段落。なので、 syncdb を叩いてデータベースへ反映する。

$ ./manage.py syncdb
Creating table auth_message
Creating table auth_group
Creating table auth_user
Creating table auth_permission
Creating table django_admin_log
Creating table django_content_type
Creating table django_session
Creating table django_site
...

ズラズラと文字が流れる途中でユーザ名とかメールアドレスとかパスワードとか聞かれるけど素直に入力。ココで設定したユーザとパスワードで管理画面にログインする事になる。

管理画面を拝むために、 urls.py のコメントアウトを外してURLとの紐付けを行う。

from django.conf.urls.defaults import *

# adminの部分のコメントアウトを外す。
urlpatterns = patterns('',
    ...
    (r'^admin/', include('django.contrib.admin.urls')),
)

これで開発サーバを起動してブラウザから /admin/ にアクセスすれば、管理画面のログイン画面が出てくるはず。 syncdb したときに入力したユーザとパスワードで入る事が出来る。

以下ココまでのまとめ?

  • startprojecttest 以外で。
  • manage.py には実行権限を立てると楽出来る。
  • Djangoutf-8 で話す。
  • 最初に syncdb したときのユーザ、パスワードは忘れるな。
  • 管理画面は最初からウハウハコンチクショー!

次はモデル作ったりとかかな?ひとまずココまで。

何にもしてないのに意外に時間かかったなぁ。

Posted at: 
2007/06/19 01:43:19
4 Comments
1 TrackBack
Tags: 
Django
Python
Trackback: 
http://humming.via-kitchen.com/2007/06/19/todo-list-by-using-django-part1/trackback/

興味シンシン

Twisted Mind さんの コチラのエントリー より。

Trac + MySQL + mod_wsgi の環境構築テストをされてるみたいです。

前に Trac 0.10.3で MySQL 使ってオオハマリしただけに、コレはちょっと興味シンシン。上手く行くといいなぁ。ってか、上手く行ってほしい!一度やってみた時にはチケットまわりでSQLエラー吐きまくってチケットが全く使えなかった。

そういえば、まだ先の事だと思って調べてなかったけど、 mod_wsgi で動く TracTracEnvParentDir とかって設定出来るんでしょうか?出来るなら乗り換えやすいんだけどなぁ。

ここはとりあえず期待して感想を待つ事にしよっと。

Posted at: 
2007/06/18 02:22:54
4 Comments
0 TrackBacks
Tags: 
mod_wsgi
MySQL
Python
Trac
Trackback: 
http://humming.via-kitchen.com/2007/06/18/very-interested-it/trackback/

apache2.2でmod_proxyを使ってみる。

前々から試してみたいなぁ。って思ってた apache 2.2での mod_proxy を、 mod_wsgi 単独の apache を立てるついでに試してしまおうと思い、実験ついでにやってみた。 apache を2つも入れるの?ってツッコミはとりあえず無しの方向で。

tar で展開する時に、展開後の名前の指定の仕方が分からなかったので、とりあえずそのまま展開してコピーする時にリネームして回避。

$ cd
$ wget http://ftp.kddilabs.jp/infosystems/apache/httpd/httpd-2.2.4.tar.gz
$ tar zxf ./httpd-2.2.4.tar.gz
$ cp -R ./httpd-2.2.4 /usr/local/src/httpd-2.2.4-proxy
$ cp -R ./httpd-2.2.4 /usr/local/src/httpd-2.2.4-wsgi

aprapr-util は共通で使いたかったので apache とは別でインストールする事に。

まずは apr から。

$ cd /usr/local/src/httpd-2.2.4-proxy/srclib/apr
$ ./configure \
> --prefix=/usr/local/apr \
> --enable-maintainer-mode \
> --enable-threads

$ make
$ sudo make install

で、次は apr-util

$ cd /usr/local/src/httpd-2.2.4-proxy/srclib/apr-util
$ ./configure \
> --prefix=/usr/local/apr \
> --with-apr=/usr/local/apr

$ make
$ sudo make install

先にインストールした aprapr-util を使って apache をインストール。モジュールに関してはDSOでしこたま入れといて、 httpd.conf でオフる方向でやる事にした。

$ cd /usr/local/src/httpd-2.2.4
$ ./configure \
> --prefix=/usr/local/httpd_proxy \
> --enable-maintainer-mode \
> --enable-mods-shared=most \
> --enable-dav \
> --enable-dav-fs \
> --enable-dav-lock \
> --enable-cgi \
> --enable-cgid \
> --enable-cache \
> --enable-mem-cache \
> --enable-proxy \
> --enable-proxy-balancer \
> --enable-so \
> --with-apr=/usr/local/apr \
> --with-apr-util=/usr/local/apr

$ make
$ sudo make install

ひとまずエラー吐かずにインストールは完了。 ここで httpd.confListenServerName だけ編集して起動してみる。ちゃんと動いた。It works!!な画面がしっかり出る。上手くいったみたいなので、 mod_proxy な設定にしてみる。

ProxyRequests Off

<Proxy *>
    Order deny,allow
    Allow from all
</Proxy>

ProxyPass / http://google.com/
ProxyPassReverse / http://google.com/

ちゃんとgoogleにフォワーディングされるものの、なぜかリクエストが / だとフォワーディングされない。

これだとあんまり意味ないので、 DocumentRoot ディレクティブと、対になる Directory ディレクティブをコメントアウトしてみたらちゃんと動くようになった。ついでに LoadModule も色々試してみた結果、

  • authz_host_module
  • proxy_module
  • proxy_http_module

だけあれば最低限動いた。本当に最低限な訳ですが。ちゃんと動かすならもうちょっと必要。 Log とか rewrite とか。

次は mod_wsgiapache なのですがそれはまた近い?うちにでも。

Posted at: 
2007/06/17 05:30:18
0 Comments
0 TrackBacks
Tags: 
apache
mod_proxy
Trackback: 
http://humming.via-kitchen.com

settings.pyをちょっとキレイに

なかなか上手い書き方が見つからない settings.py なのですが、すばらしい書き方を 記憶は削除の方向で - ちょっとした覚え書き で紹介されておりました。

こういうの、初心者にはホントにありがたいっす。さっそくやってみた。

import os

BASE_PATH = os.path.abspath(os.path.split(__file__)[0])

MEDIA_ROOT = os.path.join(BASE_PATH, 'media')

TEMPLATE_DIRS = (
    os.path.join(BASE_PATH, 'templates'),
)

mod_python からキックしてもちゃんとパスが取れてるみたい!

今まで開発環境と本番環境の違いをどうやって少なくするか?ってところで、ココが一番のネックだっただけにちょっと感動した!これからはこの書き方でいこう。素敵っす。こういう発見があると、もっとローレベルな Python も勉強しなくちゃな。って思います。

なんかワクワクしてきたよ!

Posted at: 
2007/06/16 05:13:24
0 Comments
0 TrackBacks
Tags: 
Django
Python
Trackback: 
http://humming.via-kitchen.com/2007/06/16/refactoring-settingspy/trackback/

Categories

Archives