Django:在一个循环中遍历模板中的多个连续的ManyToMany关系

发布于 2024-10-21 13:33:16 字数 1205 浏览 1 评论 0原文

我有这样的情况:有三个 Django 模型,我们称它们为文章、部分和标签,以及一个贯穿模型。

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

class Section(models.Model):
    # all sorts of fields here

class Article(models.Model):
    tags = models.ManyToManyField(Tag, null=True, blank=True)
    sections = models.ManyToManyField(Section, null=True, blank=True, through='SectionInArticle', related_name='articles')

class SectionInArticle(models.Model):
    article = models.ForeignKey(Article)
    section = models.ForeignKey(Section)
    order = models.IntegerField()

然后,在该部分的详细信息模板中,我想列出相关文章中的所有标签。为此,我首先必须反向遍历节-文章多对多关系(使用 related_name),然后遍历文章-标签多对多关系。我尝试过:

{# doesn't print anything: #}
{% for tag in object.articles.tags.all %}
{{ tag.name }}
{% endfor %}

但由于某种原因,这不起作用。 {% for tag in object.articles.all.tags.all %} 也不起作用。我可以使用嵌套循环打印所有标签,但这意味着重复成为一个问题。

{# duplicates are an issue here: #}
{% for article in object.articles.all %}
  {% for tag in article.tags.all %}
    {{ tag.name }}
  {% endfor %}
{% endfor %}

有没有一种巧妙的方法可以在 Django 模板中执行此操作,或者我是否必须将其放入视图代码中?如果是这样,最干净的方法是什么,这样我就可以避免列表中出现重复的标签?

I have a situation like this: there are three Django models, let's call them article, section and tag, and one through-model.

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

class Section(models.Model):
    # all sorts of fields here

class Article(models.Model):
    tags = models.ManyToManyField(Tag, null=True, blank=True)
    sections = models.ManyToManyField(Section, null=True, blank=True, through='SectionInArticle', related_name='articles')

class SectionInArticle(models.Model):
    article = models.ForeignKey(Article)
    section = models.ForeignKey(Section)
    order = models.IntegerField()

Then, in the section's detail template, I want to list all the tags from the related articles. To do that, I first have to traverse the Section-Article ManyToMany relationship in reverse (using the related_name), and then traverse the Article-Tag ManyToMany relationship. I tried this:

{# doesn't print anything: #}
{% for tag in object.articles.tags.all %}
{{ tag.name }}
{% endfor %}

but for some reason, that didn't work. {% for tag in object.articles.all.tags.all %} didn't work either. I can print all the tags using nested loops, but that means duplicates become a problem.

{# duplicates are an issue here: #}
{% for article in object.articles.all %}
  {% for tag in article.tags.all %}
    {{ tag.name }}
  {% endfor %}
{% endfor %}

Is there a neat way to do this in Django templates, or do I have to put it in the view code? If so, what would be the be the cleanest way to do it there so I can avoid duplicate tags in the list?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

命比纸薄 2024-10-28 13:33:16

您正在寻找的过滤器基本上是:

Tag.objects.filter(article__sections=section)

您可以将其放在您的视图中,或者您可以将其作为属性添加到您的部分模型中:

class Section(models.Model):
# all sorts of fields here
@property
def tags(self):
    return Tag.objects.filter(article__sections=self).all()

然后在模板中执行以下操作:

{% for tag in object.tags %}
    {{ tag.name }}
{% endfor %}

The filter you are looking for is basically:

Tag.objects.filter(article__sections=section)

You can put it the your view, or you could for add it to your Section model as a property:

class Section(models.Model):
# all sorts of fields here
@property
def tags(self):
    return Tag.objects.filter(article__sections=self).all()

And then in the template do:

{% for tag in object.tags %}
    {{ tag.name }}
{% endfor %}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文