如何在Django模板中显示包含多对多关系的对象列表?

gri*_*igy 11 django django-templates

我有以下型号:

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)
Run Code Online (Sandbox Code Playgroud)

在视图中,我创建了一个Entry对象列表,并希望在模板中显示元素:

   {% for entry in entries %}
     {{ entry.title }}
     {{ entry.date }}
   <!--  {% for tag in entry.tags %} {{ tag }} {% endfor %} -->
   {% endfor %}
Run Code Online (Sandbox Code Playgroud)

使用此模板代码,它会生成以下指向模板第一行(用于标记)的TemplateSyntaxError:

渲染时捕获TypeError:'ManyRelatedManager'对象不可迭代

entries变量是一个列表:

entries = Entry.objects.filter(user=user_id)
entries = list(entries)
entries.sort(key=lambda x: x.id, reverse=False)
Run Code Online (Sandbox Code Playgroud)

你知道这里可能出现什么问题以及如何解决这个问题?

我是Django的新手,所以如何调试模板的建议可能会有所帮助.

更新

即使使用此模板,我也会遇到相同的错误:

{% for entry in entries.all %}
<!-- everything is commented out here -->
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

ist*_*ble 42

无需将条目QuerySet转换为列表.此外,您可以让DB使用order_by进行排序.

entries = Entry.objects.filter(user_id=user_id).order_by('id')
Run Code Online (Sandbox Code Playgroud)

添加.all以获取关系中的所有值(就像Entry.objects.all()).

entry.tags.all
Run Code Online (Sandbox Code Playgroud)

您也可以在shell中尝试这个(我使用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: ...>]
Run Code Online (Sandbox Code Playgroud)

如果你想调用零标签的条目,请使用for..empty.

{% for tag in entry.tags.all %}
    {{ tag.name }}
{% empty %}
    No tags!
{% endfor %}
Run Code Online (Sandbox Code Playgroud)


小智 7

这是您的查询的解决方案,

通过举例来验证您的解决方案

假设一本书有多个标签,那么为了在模板上显示一本书的所有标签就可以这样

{% for tag in book.tags.all %}
  {{ tag.name }}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

Tag的模型就像,

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

    def __unicode__(self):
    return "%s" % unicode(self.name)
Run Code Online (Sandbox Code Playgroud)


gri*_*igy 5

好的。我发现了问题。我有一些不正确的代码被注释掉了。但是 Django 处理了该代码。所以 html 评论在这里不起作用。我解决了这个问题,这一切都像魅力一样。

因此,如果您不知道 - html 注释不会阻止模板处理

这是因为模板首先由 Django 处理,然后 HTML 由浏览器呈现。

  • 您可能会喜欢 {# onliner comment #} 和 {% comment %} ... {% endcomment %}。http://docs.djangoproject.com/en/dev/ref/templates/builtins/#comment (7认同)