Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

link_toがないのはなんで???

RoRには"link_to"のような便利なものがあるのにDjangoにはないんです。
Djangoの場合、URLとviewのメソッドのマッピングの自由度が高いためちょっと実現は難しい。

urlpatterns = patterns('',
    (r'^/?$',  'XXXX.XXXX', list_dict), 
    (r'^/?detail/(?P<object_id>\w)/$',  'XXXX.XXXXXX', detail_dict), 
)

のようにviewメソッドは正規表現でマッチさせるので事実本当に自由なのである。
また
url.py

list_base = 'django.views.generic.list_detail.'

urlpatterns = patterns('',
    (r'^/?$',  list_base+'object_list', list_dict), 
    (r'^/?detail/(?P<object_id>\w)/$',  list_base+'object_detail', detail_dict), 
)

このようなGeneric-Viewsを使用するとviewメソッドを全く書かないので無理。
(この辺がDjangoの楽なところだったり)
Djangoでリンクをはる場合はどーしたらよいかなと。
で良く見られる(?)解決策+αを紹介。
models.pyで

class Hoge
    .........
    def get_absolute_url(self):
        return "/hoge/detail/%s/" % (self.id)

のようにmodelにurlを返すようにしてしまえというパターン。
(某所ではこうなっていた)
でurl.py

list_base = 'django.views.generic.list_detail.'

urlpatterns = patterns('',
    (r'^/?$',  list_base+'object_list', list_dict), 
    (r'^/?detail/(?P<object_id>\w)/$',  list_base+'object_detail', detail_dict), 
)

のようにGeneric-Viewでも問題ありません。
で少しRoRっぽくするために
linktag.py

from django.template import Library
register = Library()

def link_to(text, link):
    return '<a href="'+link+'">'+text+'</a>'
link_to = register.simple_tag(link_to)

を作り
Templateで
Template.html

{% load linktag %}
{% for item in object_list %}
.....
                        {% link_to item.title item.get_absolute_url %}
.....

なんてするとちょっといいかなあと思ったけど範囲を限定すればmodelにURLを持たせなくてもいいな。
helperとして割り切って
Template.html

{% load linktag %}
{% for item in object_list %}
.....
                        {% link_to item.title item.id %}
.....

linktag.py

from django.template import Library
register = Library()

def link_to(text, id):
    return '<a href="/blog/detail/'+id+'/">'+text+'</a>'
link_to = register.simple_tag(link_to)

ってやった方がよさげ。
Generic-view使用限定ならCRUDのFormのAction指定もhelperTagで可能。
これを元にRoRのように"link_to_remote_"とか(ry
うくく。