首页 文章

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

提问于
浏览
9

我有以下型号:

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:

Caught TypeError while rendering: 'ManyRelatedManager' object is not iterable

entries变量是一个列表:

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

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

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

Update

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

{% for entry in entries.all %}
<!-- everything is commented out here -->
{% endfor %}

4 回答

  • 6

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

    entries = Entry.objects.filter(user_id=user_id).order_by('id')
    

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

    entry.tags.all
    

    您也可以在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: ...>]
    

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

    {% for tag in entry.tags.all %}
        {{ tag.name }}
    {% empty %}
        No tags!
    {% endfor %}
    
  • 40

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

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

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

    {% 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

    好 . 我发现了这个问题 . 我有一些错误的代码被注释掉了 . 但是Django处理了那段代码 . 所以html评论在这里不起作用 . 我修好了这一切,就像魅力一样 .

    所以,如果你不知道 - the html comments don't prevent template processing .

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

  • 3

    以上来自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
    

相关问题