我希望我可以在我的网站中呈现最常用标签的列表,我确实这样做了。问题是,显示的标签经常重复,我确信如果只显示唯一的标签会更好。
在我的模型中,我编写了方法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>
其中对象来自与文章表和字段表建立关系的模型,因此通过 object.articles.all
我获得了与特定字段相关的文章的所有实例。我使用详细信息在我的观点中查看。
所以,我的第一个问题是,这种方法有效吗?我的意思是,在模型类中添加新方法,或者也许我应该在 View 中添加它?。而且我仍然对 django 模板语言不满意,所以可能存在问题。而且我知道模板中有这个过滤器,例如 {{ some_object | function}} 但我读到,在模板中保留尽可能少的逻辑是一种很好的做法。
最佳答案
如果您想这样做,我会在文章
级别添加逻辑:
class Article(models.Model):
def unique_tags(self):
return Tag.objects.filter(articletag__article=self).distinct()
然后用以下方式查询:
{% for article_tag in <b>prev_article.unique_tags</b> %}
<li><a href="#">{{article_tag.tag.verbose_name}}</a></li>
{% endfor %}
通过使用.values_list
,您将获得主键的值,因此通常是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:
<b>unique_together = ('article', 'tag')</b>
所以现在您不能用相同的标签两次标记同一篇文章。因此,一旦强制执行,您可以简单地使用:
<!-- given unique_together is enforced -->
{% for article_tag in <b>prev_article.tags.all</b> %}
<li><a href="#">{{article_tag.tag.verbose_name}}</a></li>
{% endfor %}
然后您可以使用 .prefetch_lated(..)
通过恒定数量的查询加载所有相关对象。
关于python - Django,仅从相关对象中获取唯一值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52768995/