2008-03-01

djangoのgeneric viewsのobject_listでPythonの普通のlistを表示する

(以下、あまり詳しく既存の情報を調べず、手元のdjangoのコードを読んで適当に作ったもの。。)

djangoのgenericviewsのobject_listは便利だが、デフォルトではmodelのレコードしか表示できない。
一般のリストの中身などを表示する場合は、リストオブジェクトを適切にラップしてあげる必要がある。
そういう状況はマッシュアップサイトなどを作っていると、model以外からアイテムリストを取得したりするので、よくありますね。

以下、そのサンプル。
※get()メソッドでの例外の投げ方はあまり詳しく調べてないので、いい加減です。エラーが出るかも。
※まだpagenationさせて動かしていないので、その辺はこれからテストします。

from django.views.generic.list_detail import object_list
from django.core.exceptions import ObjectDoesNotExist

def list2genericviews(lst):
class GenList(list):
model = "GenList"
DoesNotExist = ObjectDoesNotExist
def __init__(self, lst):
self.extend([{"id": i, "value": x} for i, x in enumerate(lst)])
def _clone(self):
return self
def filter(self, pk=None):
return self[pk]
def count(self):
return len(self)
def get(self):
if len(self) == 0:
raise self.DoesNotExist("No item found in GenList")
if len(self) > 1:
raise AssertionError("There are multiple items in GenList")
return self[0]
return GenList(lst)

def show_list(request):
items = ["apple", "banana", "orange"]

#引数template_nameは必須です。
return object_list(request, queryset=list2genericviews(items), template_name="itemlist.html")

テンプレートitemlist.htmlはこんな感じ。
{% if object_list %}
<ul>
{% for item in object_list %}
<li>{{ item.value }}</li>
{% endfor %}
</ul>
{% endif %}