使用ManyToMany关系中的布尔值注释查询集

问题描述 投票:0回答:2

假设我有一个像这样的

Book
模型:

class Book(models.Model)
    title = models.Charfield(...)
    likes = models.ManyToMany(User, related_name="books_liked")

我需要使用当前登录用户的

is_liked
字段注释查询集。

我在视图中有这个,但它不起作用:

    user = self.request.user
    qs = Book.objects.all().annotate(is_liked=Exists(user.books_liked.all()))
    return qs

所以我可以在模板中使用类似的东西

{% for book in books %}
    {% if book.is_liked %}
      ...
    {% endif %}
{% endfor %}

我正在检查此文档部分,但我不太确定如何继续或是否是正确的方法。

https://docs.djangoproject.com/en/3.1/ref/models/expressions/#exists-subqueries

我该怎么做?谢谢。

django django-models django-queryset
2个回答
0
投票

为了使其工作,我必须创建一个明确的 Like 模型:

class Like(models.Model):
    book = models.ForeignKey(
        Book, on_delete=models.CASCADE,
   )
    user = models.ForeignKey(
        User, on_delete=models.CASCADE,
    )

并删除

ManyToMany
 上的 
Book

关系

然后在视图中这样:

    qs = super().get_queryset()
    user_likes = Like.objects.filter(
        book=OuterRef("pk"),
        user=self.request.user
    )
    return Book.objects.annotate(
        is_liked=Exists(user_likes)
    )

0
投票

虽然有点晚了,但是。可以通过使用 SQL 逻辑而不需要显式模型来解决这个问题。只需使用 CASE WHEN 即可。

from django.db.models import Case, When, Value

user_id = self.request.user.id
qs = Book.objects.annotate(is_liked=Case(
    When(likes__id=user_id, then=Value(True)),
    default=False
)        

其余工作正常。

© www.soinside.com 2019 - 2024. All rights reserved.