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

Posted

技术标签:

【中文标题】Django模板:循环并打印对象的所有可用属性?【英文标题】:Django templates: loop through and print all available properties of an object? 【发布时间】:2011-01-14 02:52:26 【问题描述】:

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

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

例如,有一个名为“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 %

希望这是有道理的......

【问题讨论】:

完全重复:***.com/questions/2170228/… 【参考方案1】:

您可以向 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 %

【讨论】:

完美运行——正是我想要的。谢谢! 你知道我怎样才能以某种方式在值旁边返回 field.verbose_name 吗?我想这只是正确的 Django 语法的问题,但我很困惑:( 我对原来的答案做了一些更改。附加到字段的名称属性应该给你你想要的。 再次感谢您!只做需要的事情。 非常优雅。如果您想要更多的控制(例如解析选项列表/选择字段或排除某些字段的能力,请参阅这个更详细的模型方法版本,它获取所有字段并将它们返回到模板:***.com/questions/2170228/…跨度> 【参考方案2】:

以下方法只需要定义一个自定义模板过滤器 (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。

【讨论】:

我使用return [(field.name, field.verbose_name, field.value_to_string(obj)) for field in obj._meta.fields] 在模板中显示verbose_name 而不是name【参考方案3】:

在 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

【讨论】:

以上是关于Django模板:循环并打印对象的所有可用属性?的主要内容,如果未能解决你的问题,请参考以下文章

打印 Smarty 模板中可用的所有变量

django模板标签运行循环不是所有对象[重复]

django 打印 cmd 中的所有记录,但在模板上显示最后一条

Django 模版语法与使用

Django如何循环对象并在模板中显示变量

Django 模板:有没有办法根据其属性查询特定对象(而不是遍历所有对象)?