这似乎相当简单,但我无法从SO或Django文档中找到一个好的解决方案(使用Django 1.10)
我在模板中获取一个模型对象,并且只显示那些具有值(即非空或空)或不是空的字段(如果是ManyToManyField。
除了使用许多if
和else
来检查字段类型然后运行相应的{{1>之外,我无法找到一个好方法。条件。
if
始终为{% if model_name.field_name %}
s返回true
(因为它是ManytoManyField
)
ManyRelatedManager
始终会为{% if model_name.field_name|length > 0 %}
s
false
ManytoManyField
可能适用于{% if model_name.field_name.all %}
但不适用于其他人(例如ManyToManyFields
)
是否有一种方法可以检查字段中是否包含某些可用值(是CharField
还是简单ManytoManyField
)?我可以先使用多个CharField
来检查字段类型,然后运行相应的检查,但这样做会让人觉得反直觉,因为这感觉就像是一个常见的用例来证明模板标签的合理性。
答案 0 :(得分:2)
您可以使用Prelude> let g = \h -> h . g
<interactive>:11:19:
Occurs check: cannot construct the infinite type: b ~ (b -> c) -> c
:https://docs.djangoproject.com/en/1.11/ref/models/meta/#retrieving-all-field-instances-of-a-model
所以在你的情况下,它看起来像这样(这是伪代码):
get_fields
但我同意@ cezar的意见,你应该将这样的内容移到{% for field in Model._meta.get_fields() %}
{% if field.get_internal_type() == "ManyToManyField" %}
... # render m2m, here you could use gettatr
{% else %}
... # render regular field, here you could use gettatr
{% endif %}
{% endfor %}
答案 1 :(得分:1)
这就是我最终做的事情:
@ cezar的建议是有道理的,所以我将逻辑移到了views.py
(毕竟,是否显示值的逻辑,将落在什么显示的桶中,因此进入视图而不是模板中的展示方式)
此外,不是将模型对象返回到模板,而是返回一个只包含相关值的dict。 ManyToManyFields(如果不为空)在dict中显示为列表。
for field in school._meta.get_fields(): # where school is the model object
#checking if field type is m2m
if (field.get_internal_type() == 'ManyToManyField'):
if getattr(school,field.name).exists():
school_display[field.name] = [k.name for k in getattr(school, field.name).all()]
#checking if field has choices (so we could send the display name)
elif field.choices:
func_name_to_display = 'get_' + field.name + '_display'
#note the '()' at the end, below. getattr(a,b) is equivalent to a.b so we need to add a '()' at the end since its a function
school_display[field.name] = getattr(school,func_name_to_display)()
#just returning the value (if not empty) in other cases
else:
field_value = getattr(school,field.name)
if (field_value and field_value!='None'):
school_display[field.name] = field_value
return render(request, 'detail.html', {'school_display' : school_display})
我很高兴我这样做是因为我发现,在这个过程中,调用模型对象上的其他两个方法,理想情况下属于views.py,并且也移动了它们。
很高兴了解上述方法是否可以改进。
答案 2 :(得分:0)
如果你使用模板过滤器,那么它应该是显而易见的:
from django import template
register = template.Library()
@register.filter
def is_not_empty(field):
try:
return field.count()
except (AttributeError, TypeError):
return field