在 Django 模板中仅显示 None 值

Show only not None values in Django template

我有一个 Model 有很多属性;在我的 DetailView 呈现的模板中,我只想显示不是 None.

的属性

这可以通过检查属性值是否不是 Noneif 模板标签轻松完成,我应该为模型中的每个属性添加一个 if 条件,并且有很多。

我想遍历所有属性并if not None显示它们。 在伪代码中它看起来像这样:

{% for attribute in my_instance.all_attributes %}
  {% if attribute.value is not None %}
    {{attribute.value}}

我可以通过 class 或实例获得具体属性的元组:

cls._meta.concrete_fields

self._meta.concrete_fields

现在我的伪代码示例中有了 my_instance.all_attributes,我可以对其进行迭代,但我不知道如何获取实例属性的实际值。

编辑:

.concrete_values return 是 Field 个实例的数组,它看起来像这样:

(<django.db.models.fields.BooleanField: gov>, <django.db.models.fields.BooleanField: in_group>, <django.db.models.fields.CharField: legal_class>,)

我可以使用 .name 访问 Field 实例的名称属性值。在上面的示例中调用 .name 将 return 'gov''in_group''legal_class'

Django 的作者竭尽全力确保模板语言不会被用来做这样的事情!据我了解,他们的意见是模板应该进行格式化,Python 应该进行程序逻辑。

有两种解决方法。一种是创建模板可以循环访问的结构,并将其传递给 DetailView 上下文。像

def get_context_data(self):
    data = super().get_context_data(**kwargs)

    fieldnames = [
        x.name for x in self.object._meta.concrete_fields ]
    display_fields = [
        (name, getattr( self.object, name, None)) for name in fieldnames ]
    display_fields = [ x for x in display_fields if x[1] is not None ]

    data['display_fields'] = display_fields
    return data

现在您可以在模板中执行

{% for name,value in display_fields %} 

您可能更喜欢编写名称列表而不是使用 ._meta.concrete_fields,因为这样您可以选择名称出现的顺序。或者您可以从一个有序列表开始并附加任何在 _meta 中但尚未在您的列表中的内容(并删除任何在您的列表中但不在 _meta 中的内容)

另一种方法是使用 Jinja 作为此视图的模板引擎。