Шаблоны Django: просмотреть и распечатать все доступные свойства объекта? - PullRequest
22 голосов
/ 07 февраля 2010

У меня есть объект базы данных с именем manor_stats, около 30 полей. Для большинства строк большинство этих полей будут нулевыми.

В моем шаблоне я хотел бы перебрать все поля в строке и вывести информацию только для тех полей, которые не равны NULL.

Например, есть поле с именем «name»: я хотел бы напечатать <li>Name: {{ manor_stats.name }}</li> в шаблоне ТОЛЬКО для тех объектов, где поле не является нулевым. В идеале, я бы тоже хотел автоматически извлекать «Имя:» откуда-то, а не указывать его.

Я знаю, что могу использовать {% if manor_stats.name %}, чтобы проверить, является ли каждое поле пустым, но я не хочу делать это 30 раз для всех полей.

Вот что у меня есть в views.py:

.
manor_stats = Manors.objects.get(idx=id)
return render_to_response('place.html', { 'place' : place, 'manor_stats' : manor_stats }, context_instance = RequestContext(request))

А затем в place.html я хотел бы иметь что-то, что работает примерно так (псевдокод, где ??? указывает биты, которые я не знаю как делать):

{% if manor_stats %} 
<ul>
 {% for manor_stats.property??? in manor_stats %} 
  {% if manor_stats.property %} 
   <li>{{ manor_stats.property.field_name??? }} {{ manor_stats.property.value??? }}</li>
  {% endif %}
 {% endfor %
{% endif %}

Надеюсь, что это имеет смысл ...

Ответы [ 3 ]

49 голосов
/ 07 февраля 2010

Вы можете добавить метод к вашей модели Manors, который будет возвращать все значения полей, оттуда вы можете просто зациклить эти значения в проверке шаблона, чтобы увидеть, не является ли значение пустым.

- models.py

class Manors(models.Model)
  #field declarations

  def get_fields(self):
    return [(field.name, field.value_to_string(self)) for field in Manors._meta.fields]

- manor_detail.html

{% for name, value in manor_stats.get_fields %}
  {% if value %}
    {{ name }} => {{ value }}
  {% endif %}
{% endfor %}
3 голосов
/ 27 июля 2018

Следующий подход требует только определения отдельного пользовательского фильтра шаблона ( см. Документы ) - это DRY'er, чем необходимость писать или копировать метод в каждую модель, для которой вам нужна эта функция.

- my_app / templatetags / my_tags.py

from django import template

register = template.Library()

@register.filter
def get_fields(obj):
    return [(field.name, field.value_to_string(obj)) for field in obj._meta.fields]

Вам потребуется перезагрузить сервер, чтобы зарегистрировать новые теги и сделать их доступными в ваших шаблонах.

- my_app / templates / my_app / my_template.html

{% load my_tags %}
<ul>
{% for key, val in object|get_fields %}
  <li>{{ key }}: {{ val }}</li>
{% endfor %}
</ul>

Проверено в Django 1.11.

NB: Поскольку ._meta является частным атрибутом, его функциональные возможности могут в будущем измениться.

Благодаря другим ответам на этот пост, которые заняли у меня большую часть пути, особенно В. Перрин.

0 голосов
/ 26 мая 2018

Используйте Model._meta.get_fields () в коде Python.

>>> from django.contrib.auth.models import User
>>> User._meta.get_fields()
(<ManyToOneRel: admin.logentry>,
 <django.db.models.fields.AutoField: id>,
 <django.db.models.fields.CharField: password>,
 <django.db.models.fields.DateTimeField: last_login>,
 <django.db.models.fields.BooleanField: is_superuser>,
....

В шаблоне мы можем определить фильтр для извлечения всех полей.

├─my_app
│  │
│  ├─templatetags
│  │  │  my_filters.py
│  │

from django import template
register = template.Library()

@register.filter
def get_fields(obj):
    return obj._meta.get_fields()

{% for k,v in obj|get_fields %}
    <td> {{k}} </td>
{% endfor %}

См. Ссылку: https://docs.djangoproject.com/en/2.0/ref/models/meta/#retrieving-all-field-instances-of-a-model

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...