最近は業務で、Django
を使って雑なサイトをおためしで作る*1仕事をやっています。
一週間で作るもの決めて、とにかくスピード勝負で見せるという状況です。
最低限のチュートリアルは、一年前に実施しています。
ところで、Django
のチュートリアルを見ると、たいていは
Model
でDBとのマッピングを作成View
でModel
からデータを取得し、Template
に渡すTemplate
でそのデータを表示する
のようになっています*2。
しかし、DBの構造とは異なる形でデータを表示したい場合に、どうやってやるの?という疑問が湧きました。
ある程度正規化されたデータを崩す場合も含みます。
そこで、わりと分かりやすい辞書(dict
)を表示できるか、試しました。
要するに、ASP.NET MVC
でいうところのViewModel
が欲しいんです。
バージョン
種類 | バージョン |
---|---|
Python | 3.7.0 |
Django | 2.1.1 |
View定義
今回、Model
は登場しません。
- Views.py
class HomeView(TemplateView): template_name = "home.html" def get(self, request, *args, **kwargs): context = super(HomeView, self).get_context_data(**kwargs) context['direct'] = ["apple", "orange", "banana"] context['direct_dict'] = { "name": "fruits", "kinds": {"apple": 2, "orange": 3, "banana": 4}} return render(self.request, self.template_name, context)
context
に、Model
のインスタンスではないlist
とdict
のインスタンスを渡します。
dict
は、辞書の中に辞書を持つ、いわゆるネストした形で持たせます。
- template/home.html
よくあるやつですが、base.html
から継承し、body
だけ書けるようにしています。
{% extends "base.html" %} {% block body %} {% for f in direct %} <ul> <li>{{ f }}</li> </ul> {% endfor %} <ul> <li>{{ direct_dict.name }}</li> {% for key, value in direct_dict.kinds.items %} <ul> <li>{{ key }} - {{ value }}</li> </ul> {% endfor %} </ul> {% endblock %}
listの表示
{% for f in direct %} <ul> <li>{{ f }}</li> </ul> {% endfor %}
View
から渡したdirect
の中身を、単にループして取り出して表示できます。
dictの表示
二つの方法があるようです。
- キー名を指定して表示
<li>{{ direct_dict.name }}</li>
上記のように、変数名.キー名
とすると、そのキーの値を表示できます。
- キーと値を列挙
{% for key, value in direct_dict.kinds.items %} <ul> <li>{{ key }} - {{ value }}</li> </ul> {% endfor %}
ネストしている辞書の中身を、ループで表示します。
Python
で辞書の中身を列挙する場合、
for k, v in direct_dict.items(): print('key = %s, value = %s' % (k, v))
のように、items
を使う(ここに記載がある)こととなっています。
なんと、Template
で使う場合も一緒で良いようです。
こんな感じで表示されます。
おわりに
この調子だと、独自クラスであっても、表示可能なような気がします。
標準テンプレート*3を使う場合より生産性は落ちますが、独自クラスを使えるなら実装の選択肢が広がりそうです。
もっと使い慣れたら、いろいろ試していきます。
今回はあっさりな記事でした。