首页 文章

Django模板 - 检查字段是否有值,或者如果ManyToManyField,则为空

提问于
浏览
0

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

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

除了使用许多 ifelse 来检查字段类型然后运行相应的 if 条件之外,我无法找到一个好方法 .

{% if model_name.field_name %} 始终为 ManytoManyField s返回 true (因为它是 ManyRelatedManager

{% if model_name.field_name|length > 0 %} 始终为 ManytoManyField 返回 false

{% if model_name.field_name.all %} 可能适用于 ManyToManyFields 但不适用于其他人(如 CharField

有没有一种方法可以检查字段中是否有一些可用的值(无论是 ManytoManyField 还是简单的 CharField )?我可以先使用多个 if-else 来检查字段类型然后运行相应的检查,但这样做感觉反直觉,因为这感觉就像一个常见的用例来证明模板标签 .

3 回答

  • 0

    您可以使用 get_fieldshttps://docs.djangoproject.com/en/1.11/ref/models/meta/#retrieving-all-field-instances-of-a-model使其更清洁

    所以在你的情况下,它看起来像这样(这是伪代码):

    {% 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 %}
    

    但我同意@ cezar的评论,你应该把这样的事情转移到 views.py

  • 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

    如果你使用模板过滤器,它应该是安静的,它应该是什么样子:

    from django import template
    register = template.Library()
    
    @register.filter
    def is_not_empty(field):
        try:
            return field.count()
        except (AttributeError, TypeError):
            return field
    

相关问题