Django模板 - 检查字段是否有值,如果ManyToManyField

时间:2017-05-10 10:16:56

标签: django django-models django-templates django-template-filters

这似乎相当简单,但我无法从SO或Django文档中找到一个好的解决方案(使用Django 1.10)

我在模板中获取一个模型对象,并且只显示那些具有值(即非空或空)或不是空的字段(如果是ManyToManyField。

除了使用许多ifelse来检查字段类型然后运行相应的{{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来检查字段类型,然后运行相应的检查,但这样做会让人觉得反直觉,因为这感觉就像是一个常见的用例来证明模板标签的合理性。

3 个答案:

答案 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