日記

日々のことと、Python/Django/PHP/Laravel/nodejs などソフトウェア開発のことを書き綴ります

render_to_response の中身

いままで何気なく views.py の中で使ってしまった render_to_response ですが、何をしているのかわからないまま使うのは良くないと思ったので、今回はこの関数を使わずに同じようなことをしてみたいと思います。

まずは views.py の現状のコードを見てみます。

# vim:fileencoding=utf-8
from django.shortcuts import render_to_response
from django.template import RequestContext

def first(request):
    from datetime import datetime
    
    return render_to_response('first.html', {
      'abc': u'abcですと!',
      'none_data': None,
      'empty_string': '',
      'two_value': 2,
      }, 
      context_instance=RequestContext(request))

まぁ、見慣れたコードですね。
ちょっとノイズが多いので、削除してノイズを取り払います。

render_to_response(
  'first.html', 
  {'abc': u'abcですと!',}, 
  context_instance=RequestContext(request))

ここまで分解すると、本質が見えてきます。

- テンプレートに first.html を取っている
- テンプレートに渡す値を設定している
- Context は RequestContext を使っている

こんな感じだと思います。
じゃ、早速、views.py を書き換えて見たいと思います。

# vim:fileencoding=utf-8
from django.shortcuts import render_to_response

from django.http import HttpResponse
from django.template import loader
from django.template import RequestContext

def first(request):
    from datetime import datetime
    
    t = loader.get_template('first.html')
    c = RequestContext(request, {
      'abc': u'abcですと!',
      'none_data': None,
      'empty_string': '',
      'two_value': 2,
      })
    return HttpResponse(t.render(c))

render_to_response を使わないと、こんなコードになります。
テンプレートファイルを loader から読み込んで、自分でContextのインスタンスを生成して値を設定しています。HttpResponse は初登場ですが、これがクライアントへのレスポンスを返すための値を持ったクラスです。HttpResponseもサブクラスがいくつか存在しているので、別の機会に紹介したいと思います。

それでは、これをブラウザ経由で実行すると

<html>
<head>
</head>
<body>



<p>サンプルアプリケーション はじめの一歩</p>

87562
<p>ほげほげ</p>
16741

<p>Remote Addr: 127.0.0.1</p>

</body>
</html>

はい、前回と同じようなHTMLが出力されていますね。
面白味にかけますが、これで render_to_response が何をしているのかわかったかと思います。
render_to_response のようなショートカット関数は、http://docs.djangoproject.com/en/1.1/topics/http/shortcuts/#topics-http-shortcuts他にもあり、Djangoのマニュアルで紹介されています。
これをうまく使うと、プログラムを書く量を抑えられたり、きれいなコードになります。
その一方で、極力少ないコードで書こうとすると、Djangoの便利な機能(Context Processorが無効、Template単体利用できない)が使えなかったりします。でも、もう解説したので大丈夫!うまいこと使い分けて行きましょう。

で、これで終わりだとアレなので、少し脱線して Template を単体で使ってみます。

manage.py shell

を使って Django のshellにログインします。
そこで、次のコードを順々に実行します。

from django.template import loader
from django.template import Context

t = loader.get_template('first.html')
c = Context({
 'abc': u'abcですと!',
 'none_data': None,
 'empty_string': '',
 'two_value': 2,
})

print t.render(c)

これを実行すると

<html>
<head>
</head>
<body>



<p>サンプルアプリケーション はじめの一歩</p>

75094
<p>ほげほげ</p>
70173

<p>Remote Addr: </p>

</body>
</html>

ブラウザで実行していたものとほぼ同じ結果が表示されました!
HttpResponseに渡しているのは、Unicode文字列で、Templateを単体で使うのも簡単だとわかったと思います。なんでこんな使い方をする必要があるのか。。。簡単に文字列としてレンダリング後のデータを取れるということは、メール本文などにも簡単に流用できると言うことです。
JavaServletの世界だと、JSPの依存度は非常に高く、HTML以外で利用することはほぼ不可能でした。ViewにはJSP、メールにはVelocityなんていうことをしている人も多いのではないでしょうか。でも、Djangoだったら、そんなのお構いなし、HTMLもメールも同じテンプレートが利用できます。
こういうところまで気を配っているのは、Djangoの好きなところです。

次は、今回軽く触れただけだった HttpResponseをかじってみたいと思います。