django の評価 (2)
再開。参考にしているのは Python Webフレームワーク、第1回: DjangoとPythonを使ってWeb開発を行う という文書。
ビューの実装
まず、jobs\views.py を以下のように修正
from django.template import Context, loader from django.http import HttpResponse from jobs.models import Job def index(request): object_list = Job.objects.order_by('-pub_date')[:10] t = loader.get_template('jobs/job_list.html') c = Context({ 'object_list': object_list, }) return HttpResponse(t.render(c))
これ、テンプレートが無いと意味分かりませんな。資料にある v3 は一旦スルーして、次の節へ
テンプレート作成
まず、どこにテンプレートを置くか、な記述が必要 (置き場所の作成も)。settings.py に以下の記述を追加してディレクトリを掘る
TEMPLATE_DIRS = ( 'd:/django/djproject/templates/', )
テンプレートは継承可能との事にて、スケルトンを作成している。templates/base.html を作成し、以下の記述を追加
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>Company Site: {% block title %}Page{% endblock %}</title> {% block extrahead %}{% endblock %} </head> <body> {% block content %}{% endblock %} </body> </html>
あるいはアプリケーションのスケルトンとして以下 (templates/jobs/base.html)
{% extends "base.html" %} {% block extrahead %} <style> body { font-style: arial; } h1 { text-align: center; } .job .title { font-size: 120%; font-weight: bold; } .job .posted { font-style: italic; } </style> {% endblock %}
これはスタイルシートのみ。次が v2 なビュー (上にて記述) からロードされるテンプレートになる。(templates/jobs/job_list.html)
{% extends "jobs/base.html" %} {% block title %}Job List{% endblock %} {% block content %} <h1>Job List</h1> <ul> {% for job in object_list %} <li><a href="{{ job.id }}">{{ job.job_title }}</a></li> {% endfor %} </ul> {% endblock %}
extends が継承するナニを指定している、と類推。あるいは object_list というシンボルはビューで記述されているソレと類推。
とりあえず、これで一覧表示な準備は整ったはず。
d:\django\djproject>python manage.py runserver (出力略
で、ブラウザで http://localhost:8000/jobs にアクセス。実はテンプレートのファイル名を jobs_list.html にしてて叱られております。修正後、一応正常に表示できてますが、レコードが皆無なので出力されるのは Job List というタイトルのみ。
仕方が無いので jobs\models.py に Admin なインナークラスの定義を追加して、上書き後に速攻リロードしたらコンテンツ表示できず。サーバ側で準備ができてなかった模様。処理の終了を確認後、再試行したら Jobs も表示。
ちょっと寄り道
CRUD な管理インターフェースをいちいち作る手間がいらん、という話でしたが、Add job な画面を見るに、日付は選択できるわ Location は追加できるわでびっくり仰天。ヘッダーにはパンくずリストやらその他モロモロなリンクもある。
job テーブルに一件追加して上記コンテンツを見ると、一件追加されていたが、詳細画面なソレをまだ作成していない。
detail
まず、view を以下のように修正
from django.shortcuts import get_object_or_404, render_to_response from jobs.models import Job def index(request): object_list = Job.objects.order_by('-pub_date')[:10] return render_to_response('jobs/job_list.html', {'object_list': object_list}) def detail(request, object_id): job = get_object_or_404(Job, pk=object_id) return render_to_response('jobs/job_detail.html', {'object': job})
上記によれば jobs/job_detail.html が必要なんですね。以下を追加。
{% extends "jobs/base.html" %} {% block title %}Job Detail{% endblock %} {% block content %} <h1>Job Detail</h1> <div class="job"> <div class="title"> {{ job.job_title }} - {{ job.location }} </div> <div class="posted"> Posted: {{ job.pub_date|date:"d-M-Y" }} </div> <div class="description"> {{ job.job_description }} </div> </div> {% endblock %}
で、試験。detail が出ない。リンクを見ると http://localhost:8000/jobs/1 とかになってるし、テーブル的にも 1 という id はあるように見える。むむむ、と言いつつ jobs/views.py を以下に修正したら出た。(を
def detail(request, object_id): job = get_object_or_404(Job, pk=object_id) return render_to_response('jobs/job_detail.html', {'job': job})
いくつか気になる点
- 既存の rails アプリと DB を共有したい (特に認証部分)
- rails も確かテーブル名をデフォルトではないソレにできたはずですが、django も同様な模様 (http://ymasuda.jp/python/django/docs/model-api.html#id18)。
- フィールドも差異があるけど、rails な login_engine と共存できるのかなぁ。余計なフィールドがあってもお構いなし、なソレだったら助かるんですが。
- syncdb は列の add なんかにも対応できるのかどうか
これはやってみないと分からんな。 - 国際化
- 試験
- 静的コンテンツの取り扱い
もう少しチュートリアル等を試験しながら色々確認予定。
テーブルの名前
モデルの中でインナークラスをナニすれば良い、との事。以下のような定義を追加してみた。
class Test(models.Model): city = models.CharField(maxlength=50) state = models.CharField(maxlength=50, null=True, blank=True) country = models.CharField(maxlength=50) def __str__(self): if self.state: return "%s, %s, %s" % (self.city, self.state, self.country) else: return "%s, %s" % (self.city, self.country) class Meta: db_table = 'xxxx'
で syncdb して sqlite3 な .tables を確認
d:\django\djproject>python manage.py syncdb Creating table xxxx Adding permission 'test | Can add test' Adding permission 'test | Can change test' Adding permission 'test | Can delete test' d:\django\djproject>..\sqlite-3_3_17\sqlite3 djproject.db SQLite version 3.3.17 Enter ".help" for instructions sqlite> .table auth_group django_admin_log auth_group_permissions django_content_type auth_message django_session auth_permission django_site auth_user jobs_job auth_user_groups jobs_location auth_user_user_permissions xxxx sqlite>
名前的には良いんですが、django な認証テーブルなソレはもう少し検証が必要。ruby みたいにクラスのオーバーライドみたいな真似ができればシアワセなんですが。
認証
rails の login_engine なソレでの認証も可能に見えるな。AUTHENTICATION_BACKEND に自作の認証バックエンドなクラスを追加しておけば良さげ。あとは login_engine なテーブルにアクセスするだけなのかなぁ。
http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/models.py を確認せねば、なソレですか。