Как отобразить список объектов, содержащих отношения «многие ко многим» в шаблоне Django? - PullRequest
10 голосов
/ 22 октября 2010

У меня есть следующие модели:

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)

В представлении я создаю список объекта Entry и хочу показать элементы в шаблоне:

   {% for entry in entries %}
     {{ entry.title }}
     {{ entry.date }}
   <!--  {% for tag in entry.tags %} {{ tag }} {% endfor %} -->
   {% endfor %}

И с этим шаблоном кода он генерирует следующий TemplateSyntaxError, указывающий на первую строку шаблона (для тега):

Ошибка TypeError при рендеринге: объект ManyRelatedManager не повторяется

Переменная записей представляет собой список:

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 ]

41 голосов
/ 22 октября 2010

Нет необходимости превращать записи 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..empty .

{% for tag in entry.tags.all %}
    {{ tag.name }}
{% empty %}
    No tags!
{% endfor %}
7 голосов
/ 16 мая 2013

Вот решение вашего запроса,

Проверка вашего решения на примере

Предположим, что книга имеет количество тегов, поэтому для отображения всех тегов книги на шаблоне может быть так:

{% for tag in book.tags.all %}
  {{ tag.name }}
{% endfor %}

где модель Tag похожа,

class Tag(models.Model):
    name = models.CharField(max_length=100)

    def __unicode__(self):
    return "%s" % unicode(self.name)
4 голосов
/ 23 октября 2010

OK. Я нашел проблему. У меня был неправильный код, который был закомментирован. Но Джанго обработал этот код. Так что html комментарии здесь не работают. Я исправил это, и все это работало как шарм.

Так что, если вы не знали - html-комментарии не мешают обработке шаблона .

Это потому, что сначала Django обрабатывает шаблон, а затем браузер выводит HTML.

3 голосов
/ 22 октября 2010

Выражение 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...