我希望我可以在我的网站上显示最常用标签的列表。问题是显示的标签经常重复显示,我敢肯定,如果只显示唯一标签,效果会更好。
在我的模型中,我编写了方法unique_tags
class ArticleTag(models.Model):
article = models.ForeignKey('ep.Article', on_delete=models.CASCADE, related_name='tags')
tag = models.ForeignKey('ep.Tag', on_delete=models.CASCADE)
def unique_tags(self):
return self.objects.values_list('tag').distinct()
当我在python shell中对其进行测试时,它可以正常工作,但是它不会呈现任何标签。我的模板如下所示:
<div class="widget-tags">
<ul>
{% for prev_article in object.articles.all %}
{% for article_tag in prev_article.article.tags.all.unique_tags %}
<li><a href="#">{{article_tag.tag.verbose_name}}</a></li>
{% endfor %}
{% endfor %}
</ul>
</div>
其中对象来自与Article表和Field表建立关系的模型,因此使用object.articles.all
,我具有与特定字段相关的所有文章实例。我在视图中使用了明细视图。>
所以,我的第一个问题是,这是有效的方法吗?我的意思是,在模型类中添加新方法,还是应该在视图中添加此方法?。我仍然对django模板语言不满意,所以也许有问题。而且我知道模板中有此过滤器,例如{{some_object |函数}},但我已经读到,最好在模板中保留尽可能少的逻辑。
答案 0 :(得分:2)
如果要执行此操作,我会在Article
级别上为 添加逻辑:
class Article(models.Model):
def unique_tags(self):
return Tag.objects.filter(articletag__article=self).distinct()
,然后使用以下命令进行查询:
{% for article_tag in prev_article.unique_tags %}
<li><a href="#">{{article_tag.tag.verbose_name}}</a></li>
{% endfor %}
通过使用.values_list
,您将获得主键的 value ,因此通常是int
(或给定您自己定义主键的其他原始类型)
话虽如此,我认为最好通过在模型中添加unique_together
[Django-doc]约束条件来简单地确保这种情况永远不会发生:
class ArticleTag(models.Model):
article = models.ForeignKey(
'ep.Article',
on_delete=models.CASCADE,
related_name='tags'
)
tag = models.ForeignKey('ep.Tag', on_delete=models.CASCADE)
class Meta:
unique_together = ('article', 'tag')
所以现在您不能简单地用相同的标签对同一篇文章进行两次标签。因此,一旦强制实施,您就可以使用:
<!-- given unique_together is enforced -->
{% for article_tag in prev_article.tags.all %}
<li><a href="#">{{article_tag.tag.verbose_name}}</a></li>
{% endfor %}
然后您可以使用.prefetch_related(..)
来以恒定数量的查询加载所有相关对象。