Djangoでもemacsでgrep-gems コマンド
Djangoはpydocでみてもクラスやメソッドがよく分からないことが多いし、ドキュメント見るよりソースみた方が早いこともある。
railsでの紹介だけど
emacs での grep-gems コマンド
の方法でemacs.elを設定したら結構良い感じになった。
subversionの.svnも拾っちゃうのが邪魔だけど、それ以外は問題なし。
/site-packages/~ のを参照すると操作ミスでファイルを変更しちゃいそうなので
別途同じリビジョンのものを落として、それを見るようにしてます。
reSTを導入するも
import re, urllib register = Library() BRACKET_LINK_RE=re.compile("\[\[(.+?)\]\]") def restructuredtext_rigid(value): try: from docutils.core import publish_parts except ImportError: return value else: parts = publish_parts(source=value, settings_overrides={'doctitle_xform': False},writer_name="html4css1") return parts["fragment"] @register.filter def wikify(value): """Makes WikiWords""" def quote_link(ob): word=ob.group(1) return r'<a href="/wiki/%s">%s</a>' % (urllib.quote(word), word) #return restructuredtext_rigid(value) value = restructuredtext_rigid(value) return BRACKET_LINK_RE.sub(quote_link, value)
昨日のwikiの内容を変更するカスタムフィルターにrestructuredtextを導入しようかとあれこれテストしてみました。
続きを読むカスタムフィルター
カスタムフィルターはテンプレートの内容になんらかの変更を行うときに使います。
例えばwikiの文章のなかに
abcd[[test]]dcba
のような記述があったときに
abcd<a href="/wiki/test/">test</a>bcda
と変換させたいときは
テンプレートを以下のようにして
{% load wikitags %} {{ page.title }} <h1>{{ page.title }}</h1> <div class="body"> {{ page.body|wikify }} </div>
カスタムフィルターを以下のようにすると良い。
/myproject/wiki/templatetags/wikitags.py
from django.template import Library from django.conf import settings register = Library() @register.filter def wikify(value): """Makes WikiWords""" import re wikifier = re.compile("\[\[(.+?)\]\]") return wikifier.sub(r'<a href="/wiki/\1/">\1</a>', value)
テンプレートの
{% load wikitags %}
でtemplatetagsのwikitagsを読み込み
{{ page.body|wikify }}
でwikitagsのwikifyという関数にpage.bodyを引数で渡すことによって正規表現で書き換えられた文字列が返ってきます。
参考(というかそのまま)
http://e-scribe.com/news/171
slugの使い方
model.pyが以下の場合で
class Page(models.Model): title=models.CharField(unique=True, maxlength=200) body=models.TextField() date=models.DateField(auto_now=True) class Admin: pass def __repr__(self): return self.title
で
id=1, title="test", body="test test"
のデータあり、
url.pyを以下にした場合
info_dict={'queryset': Page.objects.all()} page_dict={'model': Page} urlpatterns=patterns('', (r'^(?P<object_id>\d+)/$','django.views.generic.list_detail.object_detail', info_dict ), (r'^(?P<slug>\w+)/$','django.views.generic.list_detail.object_detail', dict(info_dict, slug_field='title')), )
http://localhost:8000/simplewiki/1/
でも
http://localhost:8000/simplewiki/test/
でも
同じインスタンスが
/mytemplate/simplewiki/page_detail.html
に反映されます。
正規表現で取り出した(?P
slug_field='title'で伝えてるわけですね。
また、
veiw.genericは便利だけど、そのままでは使えないケースが多いので、
view.pyにコピーして弄るか、
自前のgenericをmyporjectの下に作った方がよいかもしれません。
saveとdeleteの前処理と後処理
DjangoはModelにあれこれ処理を書くことができるのが特徴だと思うのですが、
test/modeltestsをみてたら
save_delete_hooks/model.py
にsave()やdelete()に関する説明がありました。
自分のアプリのmodel.pyで作るクラスは
django/db/models/base.py
にあるModelクラスを継承して作るのですが、
save(),delete()の場合は継承元のsuperクラスに任せるようになっているようです。
""" 13. Adding hooks before/after saving and deleting To execute arbitrary code around ``save()`` and ``delete()``, just subclass the methods. """ from django.db import models class Person(models.Model): first_name = models.CharField(maxlength=20) last_name = models.CharField(maxlength=20) def __repr__(self): return "%s %s" % (self.first_name, self.last_name) def save(self): print "Before save" super(Person, self).save() # Call the "real" save() method print "After save" def delete(self): print "Before deletion" super(Person, self).delete() # Call the "real" delete() method print "After deletion" API_TESTS = """ >>> p1 = Person(first_name='John', last_name='Smith') >>> p1.save() Before save After save >>> Person.objects.all() [John Smith] >>> p1.delete() Before deletion After deletion >>> Person.objects.all() [] """
この機能によって、事前に確認をとったり、処理後にリダイレクトしたりしてるのですね。
simplewiki
djangoの勉強をちょこっとだけ、railsのscaffold程度のもの
view.pyは何も書かずに「汎用ビュー (generic view) 」だけのテスト
python manage.py startapp simplewiki
setting.pyの
INSTALLED_APPに'myproject.simplewiki'を追加
TEMPLATE_DIRSにテンプレートのパス
DATABASE関連
を書いて
下記のファイルを作って
python manage.py sql simlewiki python magage.py syncdb python manage.py runserver
でとりあえず動くかも
明日はslugだったかな?を勉強してform関連のドキュメントを読んで
他の人のコードを読んでみよう。
==myproject/urls.py from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^simplewiki/', include('myproject.simplewiki.urls')), (r'^admin/', include('django.contrib.admin.urls')), ) ==simplewiki/urls.py from django.conf.urls.defaults import * from myproject.simplewiki.models import Page info_dict={'queryset': Page.objects.all()} page_dict={'model': Page} urlpatterns = patterns('', (r'^$','django.views.generic.list_detail.object_list', info_dict ), (r'^(?P<object_id>\d+)/$','django.views.generic.list_detail.object_detail', info_dict ), (r'^(?P<object_id>\d+)/edit/$','django.views.generic.create_update.update_object', dict(page_dict, post_save_redirect="/simplewiki/")), (r'^(?P<object_id>\d+)/delete/$','django.views.generic.create_update.delete_object', dict(page_dict, post_delete_redirect="/simplewiki/")), (r'^add/$','django.views.generic.create_update.create_object', dict(page_dict, post_save_redirect="/simplewiki/")), ) ==simplewiki/models.py from django.db import models # Create your models here. class Page(models.Model): title=models.CharField(unique=True, maxlength=200) body=models.TextField() date=models.DateField(auto_now=True) class Admin: pass def __repr__(self): return self.title ==myproject/mytemplate/simplewiki/page_list.html <ul> {% for page in object_list %} <li><a href="/simplewiki/{{ page.id }}">{{ page.title }}</a></li> {% endfor %} <a href="/simplewiki/add">create page</a> </ul> ==myproject/mytemplate/simplewiki/page_detail.html <h1>{{ object.title }}</h1> <p>{{ object.body }}</p> {{ object.date }}<br/> <a href="edit">edit</a><br/> <a href="delete">delete</a><br/> ==myproject/mytemplate/simplewiki/page_form.html {% if object %} <form method="post" action="/simplewiki/{{ object.id }}/edit/"> {% else %} <form method="post" action="/simplewiki/add/"> {% endif %} {{ form.title }}<br/> {{ form.body }}<br/> <input type="submit" name="type" /> </form> ==myproject/mytemplate/simplewiki/page_confirm_delete.html <form method="post" action="/simplewiki/{{ object.id }}/delete/"> {{ object.title }} <br/> <input type="submit" name="type" /> </form>