我在Google App Engine中使用Django。如果我有班级
class Person():
first_name = StringProperty()
last_name = StringProperty()
我有一个Person.first_name = Bob和Person.last_name = Vance的实例,我可以创建一个迭代Person属性的模板来生成:
<tr>
<td>First</td>
<td>Bob</td>
</tr>
<tr>
<td>Last</td>
<td>Vance</td>
</tr>
也许更简洁一点,是否有一个model.as_table()方法可以打印出我的实例Bob Vance的属性?
答案 0 :(得分:8)
在模板中,您无法访问__underscored__属性或函数。 我建议您在模型/类中创建一个函数:
class Person(models.Model):
first_name = models.CharField(max_length=256)
last_name = models.CharField(max_length=256)
def attrs(self):
for attr, value in self.__dict__.iteritems():
yield attr, value
def sorted_attrs(self):
# Silly example of sorting
return [(key, self.__dict__[key]) for key in sorted(self.__dict__)]
在模板中它只是:
<tr>
{% for name, value in person.attrs %}
<td>{{name}}</td>
<td>{{value}}</td>
{% endfor %}
</tr>
现在这会给你“first_name”而不是“First”,但你明白了。您可以将方法扩展为mixin,或者存在于父类等中。 同样,如果你想要迭代一些人对象,你可以使用它:
{% for person in persons %}
<tr>
{% for name, value in person.attrs %}
<td>{{name}}</td>
<td>{{value}}</td>
{% endfor %}
</tr>
{% endfor %}
答案 1 :(得分:2)
变化:
for attr, value in a.__dict__.iteritems():
为:
for attr, value in self.__dict__.iteritems():
答案 2 :(得分:2)
最后在dev邮件列表(http://groups.google.com/group/django-developers/browse_thread/thread/44cd834438cfda77/557f53697658ab04?lnk=gst&q=template+model#557f53697658ab04)上找到了一个很好的解决方案:
在视图中添加:
from django.forms.models import model_to_dict
def show(request, object_id):
object = FooForm(data=model_to_dict(Foo.objects.get(pk=object_id)))
return render_to_response('foo/foo_detail.html', {'object': object})
在模板中添加:
{% for field in object %}
<li><b>{{ field.label }}:</b> {{ field.data }}</li>
{% endfor %}
答案 3 :(得分:0)
def model_to_dict(instance, fields=None, exclude=None):
"""
Returns a dict containing the data in the ``instance`` where:
data = {'lable': 'verbose_name', 'name':name, 'value':value,}
Verbose_name is capitalized, order of fields is respected.
``fields`` is an optional list of field names. If provided, only the named
fields will be included in the returned dict.
``exclude`` is an optional list of field names. If provided, the named
fields will be excluded from the returned dict, even if they are listed in
the ``fields`` argument.
"""
data = []
if instance:
opts = instance._meta
for f in opts.fields:
if not f.editable:
continue
if fields and not f.name in fields:
continue
if exclude and f.name in exclude:
continue
value = f.value_from_object(instance)
# load the display name of choice fields
get_choice = 'get_'+f.name+'_display'
if hasattr(instance, get_choice):
value = getattr(instance, get_choice)()
# only display fields with values and skip the reset
if value:
if fields:
data.insert(fields.index(f.name), {'lable': f.verbose_name.capitalize(), 'name':f.name, 'value':value,})
else:
data.append({'lable': f.verbose_name.capitalize(), 'name':f.name, 'value':value,})
return data