Показывать в шаблоне Django только значения not None
У меня есть Model с многочисленными атрибутами; в шаблоне, отображаемом моим DetailView, я хочу показать только те атрибуты, которые не являются None.
Это можно легко сделать с помощью тега шаблона if, который проверяет, не является ли значение атрибута None, но я должен добавить условие if для каждого атрибута в моей модели, а их очень много.
Я хотел бы перебрать все атрибуты и if not None отобразить их.
В псевдокоде это будет выглядеть следующим образом:
{% for attribute in my_instance.all_attributes %}
{% if attribute.value is not None %}
{{attribute.value}}
Я могу получить кортеж конкретных атрибутов как через класс, так и через экземпляр:
cls._meta.concrete_fields
или
self._meta.concrete_fields
Теперь, когда у меня есть my_instance.all_attributes в моем примере псевдокода, я могу его итерировать, но я не знаю, как получить фактическое значение атрибута экземпляра.
Авторы 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 в качестве шаблонизатора для этого представления.