Django:在显示文章列表时,根据用户显示每个文章的收藏状态

时间:2018-08-15 04:54:33

标签: 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个用户的数据以及该文章太多了。

是否有一种方法可以让我传递用户信息,使我只能获得与该用户有关的每篇文章的收藏数据,因此我可以节省查询和传递给前端的数据量。

3 个答案:

答案 0 :(得分:1)

要么在您的视图上下文中执行,要么以a custom template tag的身份执行。

下面的示例是经过干燥编码的,因此它们可能存在愚蠢的错误。

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

62.138.239.45

用法:

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 %} ,您可以执行类似的操作

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

答案 1 :(得分:0)

我假设您需要标记来说明用户是否已将该文章标记为收藏,假设有100篇文章,并且其中用户已将40篇文章标记为收藏,那么何时发送数据,然后发送100条商品数据,其中40条商品的标记为TRUE,其余为FALSE。

以下是等效的SQL,您可以根据需要将其转换为Django ORM。 'xyz'是您需要为其显示文章的用户ID

<span ng-show="inputIsRequired"> Input is required and must not exceed 45 characters.<span>
<span ng-show="InputIsInvalid">Input is invalid.<span>
<span ng-show="InputIsUnique">Input needs to be unique.<span>

答案 2 :(得分:0)

我从https://stackoverflow.com/a/51889455/2897115找到了以下答案。使用注释和子查询。使用我从中读取的注释和子查询,Django可以更快。 https://medium.com/@hansonkd/the-dramatic-benefits-of-django-subqueries-and-annotations-4195e0dafb16

我将使用https://stackoverflow.com/a/51889455/2897115中给出的解决方案。使用注释

qs = Post.objects.all()
sub = Like.objects.filter(post__id=OuterRef('pk'), user=request.user)

values = qs.annotate(
    date=Func(F('date'), function='db_specific_date_formatting_func'),
    current_user_like=Exists(sub)
).values('text, 'date', 'current_user_like')