首页 > 解决方案 > Django:在显示文章列表时,根据用户显示每篇文章的收藏状态

问题描述

我有按日期显示的文章列表。每个用户都可以将任何文章标记为他的最爱。

如果用户已登录,那么他应该能够看到该文章是否已被标记为他的最爱的一些指示。

以下是我的模型:

class Favourite(models.Model):
    user = models.ForeignKey(User,on_delete=models.CASCADE)
    date = models.DateTimeField(auto_now_add=True)
    article = models.ForeignKey(Article, null=True,on_delete=models.CASCADE)
    class Meta:
        unique_together = ('user', 'article')

class Article(models.Model):
    title = models.CharField(max_length=256)
    intro_image = models.ImageField(null=True, blank=True, upload_to=doc_hash)
    description = models.TextField(null=True, blank=True)

我想为每篇文章获取所有将该文章标记为收藏的用户 ID,然后在前端与当前用户进行检查。

但是,如果某篇文章被 1000 位用户标记为收藏,那么我将不必要地获取 1000 位用户的数据以及该文章太多了。

有没有办法,如果我通过用户,我可以只为每篇文章获取关于该用户的最喜欢的数据,这样我就可以保存查询和要传递到前端的数据量。

标签: django

解决方案


在视图的上下文中或作为自定义模板标签执行此操作。

下面的例子是干编码的,所以它们可能有一些愚蠢的错误。

在视图中(假设基于类的视图):

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['is_favourite'] = Favourite.objects.filter(user=self.request.user, article=self.object).exists()
    return context

用法:

{% if is_favourite %}Yay, you like it!{% endif %}

或模板标签:

@register.simple_tag(takes_context=True)
def is_favourite(context, article):
    request = context['request']
    return Favourite.objects.filter(user=request.user, article=article).exists()

用法:

{% is_favourite article as fav %}
{% if fav %}Yay, you like it!{% endif %}

编辑

对于 a ListView,您可以执行类似的操作

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['favourited_ids'] = set(Favourite.objects.filter(user=self.request.user, article__in=context['object_list']).values_list('article_id', flat=True))
    return context

并使用它

 {% if article.id in favourited_ids %}Yay, you like this article!{% endif %}

推荐阅读