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模板:循环并打印对象的所有可用属性?的主要内容,如果未能解决你的问题,请参考以下文章