Django模板:循环并打印对象的所有可用属性?

时间:2010-02-07 17:07:38

标签: django django-templates

我有一个名为manor_stats的数据库对象,大约有30个字段。对于大多数行,这些字段中的大多数将为null。

在我的模板中,我想循环遍历行中的所有字段,并仅打印非空字段的信息。

例如,有一个名为“name”的字段:我想在模板中打印<li>Name: {{ manor_stats.name }}</li>仅适用于字段不为空的对象。理想情况下,我也想自动从某个地方提取“名字:”,而不是指定它。

我知道我可以使用{% if manor_stats.name %}检查每个字段是否为空,但我不想对所有字段执行30次。

这是我在views.py中的内容:

manor_stats = Manors.objects.get(idx=id)
return render_to_response('place.html', { 'place' : place, 'manor_stats' : manor_stats }, context_instance = RequestContext(request))

然后在place.html中,我希望有一些大致类似的东西(伪代码,用???表示我不知道怎么做的位):

{% if manor_stats %} 
<ul>
 {% for manor_stats.property??? in manor_stats %} 
  {% if manor_stats.property %} 
   <li>{{ manor_stats.property.field_name??? }} {{ manor_stats.property.value??? }}</li>
  {% endif %}
 {% endfor %
{% endif %}

希望有道理......

3 个答案:

答案 0 :(得分:49)

您可以向Manors模型添加一个返回所有字段值的方法,然后您可以在模板中循环显示这些值,以查看该值是否为空。

- models.py

class Manors(models.Model)
  #field declarations

  def get_fields(self):
    return [(field.name, field.value_to_string(self)) for field in Manors._meta.fields]

- manor_detail.html

{% for name, value in manor_stats.get_fields %}
  {% if value %}
    {{ name }} => {{ value }}
  {% endif %}
{% endfor %}

答案 1 :(得分:3)

以下方法仅需要定义一个自定义模板过滤器(see the docs)-比必须将方法编写或复制到需要此功能的每个模型中的方法要干燥。

-my_app / templatetags / my_tags.py

from django import template

register = template.Library()

@register.filter
def get_fields(obj):
    return [(field.name, field.value_to_string(obj)) for field in obj._meta.fields]

您需要重新启动服务器才能在模板中注册并使用新标签。

-my_app / templates / my_app / my_template.html

{% load my_tags %}
<ul>
{% for key, val in object|get_fields %}
  <li>{{ key }}: {{ val }}</li>
{% endfor %}
</ul>

在Django 1.11中进行了测试。

注意::由于._meta是私有属性,因此其功能将来可能会发生变化。

感谢这篇文章中的其他回答,这些问题带给了我大部分时间,尤其是W. Perrin。

答案 2 :(得分:0)

在python代码中使用Model._meta.get_fields()。

>>> from django.contrib.auth.models import User
>>> User._meta.get_fields()
(<ManyToOneRel: admin.logentry>,
 <django.db.models.fields.AutoField: id>,
 <django.db.models.fields.CharField: password>,
 <django.db.models.fields.DateTimeField: last_login>,
 <django.db.models.fields.BooleanField: is_superuser>,
....

在模板中,我们可以定义一个过滤器来检索所有字段。

├─my_app
│  │
│  ├─templatetags
│  │  │  my_filters.py
│  │

from django import template
register = template.Library()

@register.filter
def get_fields(obj):
    return obj._meta.get_fields()

{% for k,v in obj|get_fields %}
    <td> {{k}} </td>
{% endfor %}

请参阅此链接:https://docs.djangoproject.com/en/2.0/ref/models/meta/#retrieving-all-field-instances-of-a-model