wiki20 in Django

TurboGearsのwiki20をDjangoでやってみました。

まだまだ改良の余地が大ありだと思います。
DjangoはTurboGearsと比べられがちですが、
かなり違う作りでした。

両方ともPython使いにとって素敵なフレームワークであることは間違いありません。

settings.pyは長いし個人情報がたっぷりなので省略させていただきました。

以下ソース

views.py

from django.shortcuts import render_to_response
from django.http import HttpResponse, HttpResponseRedirect, Http404
from wiki20.root.models import Page
from django.utils.simplejson import dumps

def index(request, pagename='FrontPage'):
    try:
        page = Page.objects.get(pagename=pagename)
    except Page.DoesNotExist:
        raise Http404

    return render_to_response('root/page.html', dict(page=page))

def edit(request, pagename):
    page = Page.objects.get(pagename=pagename)
    
    return render_to_response('root/edit.html', dict(page=page))

def save(request):
    pagename = request.POST['pagename']
    data = request.POST['data']
    
    page = Page.objects.get(pagename=pagename)
    page.data = data
    page.save()
    
    return HttpResponseRedirect('/%s' % pagename)

def pagelist(self):
    pages = [page.pagename for page in Page.objects.order_by('pagename')]
    pages = dumps(dict(pages=pages), ensure_ascii=False)
    
    return HttpResponse(pages, mimetype="text/javascript")

もう少し丁寧に書けそうです。
simplejsonでは日本語が通らないという切ない現実が。

Djangoでsimplejsonを使おうとしてはまりちゅう | スパムとか - Mozilla Firefox
chrome://browser/content/browser.xul

で問題を取り上げていて

Django | Code | #2427 ([patch] ensure_ascii option doesn't pass to simplejson.dump)
http://code.djangoproject.com/ticket/2427

で差分パッチを公開されています。

ジェネリックビューだかを覚えればもっとシンプルに書けそうです。

http://ymasuda.jp/python/django/docs/generic_views.html

models.py

from django.db import models

class Page(models.Model):
    pagename = models.CharField(primary_key=True, maxlength=30)
    data = models.TextField()
    
    class Admin:
        pass

Admin部分は特に変更しておりません。
もっと丁寧に書けば見やすいんでしょうねぇ。

urls.py

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

urlpatterns = patterns('',
    (r'^$', 'wiki20.root.views.index'),
    (r'^(?P<pagename>.+)/edit/$', 'wiki20.root.views.edit'),
    (r'^save/$', 'wiki20.root.views.save'),
    (r'^pagelist/$', 'wiki20.root.views.pagelist'),

    (r'^admin/', include('django.contrib.admin.urls')),

    (r'^(?P<pagename>.+)/$', 'wiki20.root.views.index'),
)

if settings.DEBUG:
    urlpatterns += patterns('',
        (r'^static/(.*)$', 'django.views.static.serve',
        {'document_root': 'E:/python/static', 'show_indexes': True}),
    )

これは自分の勉強不足が色々出ています。
とりあえず正規表現が中途半端にしか理解していない。

CherryPyの癖が抜けないで書いている。

master.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="jp" lang="jp">
<head >
    <meta content="text/html; charset=UTF-8" http-equiv="content-type"/>
    <meta http-equiv="Content-Language" content="jp" />
    <title>{% block title %}Welcome to Django{% endblock %}</title>
    <script src="/static/MochiKit.js" type="text/javascript"></script>
    <script type="text/javascript">
      function requestPageList() {
        var d = loadJSONDoc("/pagelist/");
        d.addCallback(showPageList);
      }
      function showPageList(result) {
        var currentpagelist = UL(null, map(row_display, result["pages"]));
        replaceChildNodes("pagelist", currentpagelist);
      }
      function row_display(pagename) {
          return LI(null, A({"href" : "/" + pagename}, pagename))
      }
    </script>
</head>

<body>
  {% block side %}
    <div style="float:right; width: 10em">
      {% block name %}Viewing{% endblock %} {{ page.pagename }}
      <br/>
      You can return to the <a href="/">FrontPage</a>.
    </div>
  {% endblock %}
  {% block content %}
  {% endblock %}
  
  <p>View the <a href="#" onclick="requestPageList()">complete list of pages.</a></p>
  <div id="pagelist">
  </div>
  <p align="right"><img src="Djangologo.gif"/></p>
</body>
</html>

がんばって継承を使ってみるテスツ

page.html

{% extends "master.html" %}

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

{% block content %}
{{ page.data|linebreaksbr }}
<p><a href="/{{ page.pagename }}/edit/">Edit this page</a></p>
{% endblock %}

edit.html

{% extends "master.html" %}

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

{% block content %}
<form action="/save/" method="post">
  <input type="hidden" name="pagename" value="{{ page.pagename }}"/>
  <textarea name="data" rows="10" cols="60">{{ page.data }}</textarea>
  <input type="submit" value="Save"/>
</form>
{% endblock %}

html部分はそのまんまですね。

本当に動くのコレ?とか言われそうなのでキャプチャ画像も張ってみます。

f:id:Voluntas:20060822225447p:image

f:id:Voluntas:20060822225743p:image

f:id:Voluntas:20060822225509p:image

f:id:Voluntas:20060822225520p:image

果てなだと意外にキレイに画像がアップできない切ない事実。
なんかいいところないだろうか。

こんなところです。

これからDjangoを始めようとしている人の参考に少しでもなれば(ならないと思うけど。