Как отобразить список объектов, содержащих отношения "многие ко многим" в шаблоне Django?
у меня есть следующие модели:
class Tag(models.Model):
name = models.CharField(max_length=20)
class Entry(models.Model):
title = models.CharField(max_length=100)
date = models.DateField()
tags = models.ManyToManyField(Tag)
в представлении я создаю список объектов ввода и хочу показать элементы в шаблоне:
{% for entry in entries %}
{{ entry.title }}
{{ entry.date }}
<!-- {% for tag in entry.tags %} {{ tag }} {% endfor %} -->
{% endfor %}
и с этим кодом шаблона он генерирует следующий TemplateSyntaxError, указывающий на первую строку шаблона (для тега):
пойманный TypeError во время рендеринга: объект "ManyRelatedManager" не является итерабельным
переменная entries является список:
entries = Entry.objects.filter(user=user_id)
entries = list(entries)
entries.sort(key=lambda x: x.id, reverse=False)
знаете ли вы, что может быть проблема и как решить этот вопрос?
Я новичок в Django, поэтому любые предложения по отладке шаблонов могут быть полезны.
обновление
Я получаю ту же ошибку, даже с этим шаблоном:
{% for entry in entries.all %}
<!-- everything is commented out here -->
{% endfor %}
4 ответов
нет необходимости превращать записи QuerySet в список. Кроме того, вы можете позволить БД выполнять сортировку с помощью order_by.
entries = Entry.objects.filter(user_id=user_id).order_by('id')
добавить .all
чтобы получить все значения из отношения (просто как Entry.objects.all()
).
entry.tags.all
вы также можете попробовать это в оболочке (я использую ipython, чтобы ваш вывод мог выглядеть иначе):
$ ./manage.py shell
# ...
In [1]: from yourproject.models import Entry, Tags
In [2]: entry = Entry.objects.all()[0]
In [3]: entry.tags
Out[3]: <django.db.models.fields.related.ManyRelatedManager object at 0x...>
In [4]: entry.tags.all() # for an entry with no tags.
Out[4]: []
In [5]: # add a few tags
In [6]: for n in ('bodywork', 'happy', 'muscles'):
...: t, created = Tag.objects.get_or_create(name=n)
...: entry.tags.add(t)
In [7]: entry.tags.all()
Out[7]: [<Tag: ...>, <Tag: ...>, <Tag: ...>]
и если вы хотите вызвать записи с нулевыми тегами, используйте for..пусто.
{% for tag in entry.tags.all %}
{{ tag.name }}
{% empty %}
No tags!
{% endfor %}
вот решение вашего запроса,
проверка вашего решения, приведя пример
предположим, что книга имеет количество тегов, поэтому для отображения всех тегов книги по шаблону может быть так:
{% for tag in book.tags.all %}
{{ tag.name }}
{% endfor %}
где модель тег вроде
class Tag(models.Model):
name = models.CharField(max_length=100)
def __unicode__(self):
return "%s" % unicode(self.name)
OK. Я нашел проблему. У меня был неправильный код, который был прокомментирован. Но Джанго обработал этот код. Поэтому HTML-комментарии здесь не работали. Я исправил это, и все сработало как по волшебству.
Итак, если вы не знали - HTML-комментарии не препятствуют обработке шаблонов.
Это потому, что шаблон обрабатывается Django сначала, а затем HTML визуализируется браузером.
вышеизложенное из istruble правильно, но если ваш вопрос содержит весь ваш код, вам нужно указать свойство в вашем шаблоне:
{% for entry in entries %}
{{ entry.title }}
{{ entry.date }}
{% for tag in entry.tags.all %} {{ tag.name }} {% endfor %}
{% endfor %}
или unicode функции для вашей модели:
class Tag(models.Model):
name = models.CharField(max_length=20)
def __unicode__(self):
return self.name