Django模板无法识别getattr,动态显示表格报错求助
Django模板动态展示表格:字段值获取错误的解决方法
问题场景与代码
我想在Django HTML模板中动态展示表格,相关代码如下:
视图代码
def get_object(request): objects = MyObject.objects.all() return render(request, 'table.html', {'myObjects': objects, 'fields': ObjectAdmin.list_display})
模板代码(table.html)
<thead class="tables-success"> <tr> {% for field in fields %} <th>{{ field }}</th> {% endfor %} </tr> </thead> {% for row in myObjects %} <tr> {% for field in fields %} <td>{{ getattr(row, field) }}</td> <!--<td>{{ row|getattr:field }}</td>--> {% endfor %} </tr> {% endfor %}
Admin代码(admin.py)
class MyObjectAdmin(admin.ModelAdmin): list_display = ['name'] list_per_page = 8 search_fields = ['name'] admin.site.register(Object, MyObjectAdmin)
遇到的错误
- 使用
{{ getattr(row, field) }}时,报错:
Could not parse the remainder: '(row, field)' from 'getattr(row, field)'
- 使用
{{ row|getattr:field }}时,报错:
Exception Value: Invalid filter: 'getattr'
错误原因
Django模板语法不允许直接调用Python内置函数(如getattr),且默认模板过滤器中没有getattr,因此两种写法均会触发错误。
解决方法
方案1:视图层预处理数据
在视图中提前将每个对象的指定字段值组装为字典,直接传递给模板使用:
def get_object(request): objects = MyObject.objects.all() fields = ObjectAdmin.list_display # 预处理对象,生成包含指定字段的字典列表 processed_objects = [{field: getattr(obj, field) for field in fields} for obj in objects] return render(request, 'table.html', {'myObjects': processed_objects, 'fields': fields})
模板中直接通过键访问:
{% for row in myObjects %} <tr> {% for field in fields %} <td>{{ row[field] }}</td> {% endfor %} </tr> {% endfor %}
方案2:自定义getattr模板过滤器
- 在Django app中创建
templatetags目录,添加__init__.py和custom_filters.py文件 custom_filters.py代码:
from django import template register = template.Library() @register.filter def getattr(obj, attr): return getattr(obj, attr, None) # None为默认返回值,可按需修改
- 模板中加载并使用过滤器:
{% load custom_filters %} <thead class="tables-success"> <tr> {% for field in fields %} <th>{{ field }}</th> {% endfor %} </tr> </thead> {% for row in myObjects %} <tr> {% for field in fields %} <td>{{ row|getattr:field }}</td> {% endfor %} </tr> {% endfor %}
注意:需确保当前app已添加到INSTALLED_APPS中。
方案3:利用模型__dict__属性(仅适用于数据库字段)
如果list_display中的字段都是模型直接的数据库字段,可直接访问对象的__dict__属性:
{% for row in myObjects %} <tr> {% for field in fields %} <td>{{ row.__dict__[field] }}</td> {% endfor %} </tr> {% endfor %}
此方法不支持list_display中包含自定义方法或属性的场景。
内容的提问来源于stack exchange,提问作者Diego Quirós
相关产品推荐
相关产品推荐

