布尔注释导致重复?

2024-01-12

我正在尝试实现一个基于外键表的基本“收藏夹”系统。

假设我有以下简单模型:

class Item(models.Model)
  id = models.IntegerField()

class User(models.Model)
  id = models.IntegerField()

class UserFavourites(models.Model)
  user = models.ForeignKey(User, related_name='user_for_fav_rel')
  item = models.ForeignKey(Item, related_name='item_for_fav_rel')

现在,我为项目生成以下查询集,以查看它们是否已被用户标记为收藏夹:

queryset = Item.objects.all()

USER_ID = request.user.id

queryset = queryset.annotate(
    favourite=Case(
        When(
            item_for_fav_rel__user__id=USER_ID,
            then=Value('True')
        ),
        default=Value('False'),
        output_field=BooleanField()
    )
)

所有这些都很好,但在响应中,如果该项目确实被收藏,我会收到查询集中该特定项目的副本。知道如何避免这种情况吗?

结果 SQL 查询(编辑到我认为的最小示例......)

SELECT 
    "core_item"."id", 
    CASE 
        WHEN "core_userfavourites"."user_id" = 1 THEN True 
        ELSE False 
    END AS "favourite" 
FROM "core_item" 
LEFT OUTER JOIN "core_userfavourites" 
    ON ("core_item"."id" = "core_userfavourites"."item_id")

问题是您为 core_item 和 core_userfavorites 的每种组合获取一行。似乎没有一种方法可以在没有原始 SQL 的情况下完全完成您正在尝试的操作,但幸运的是 Django 最近(1.11)添加了编写子查询子句的功能,您可以在此处使用

from django.db.models.expressions import OuterRef, Subquery

queryset = Item.objects.all()

USER_ID = request.user.id
user_favorites = UserFavourites.objects.filter(
    user_id=USER_ID, 
    item_id=OuterRef('id')
)[:1].values('user_id')

queryset = queryset.annotate(user_favorite=Subquery(user_favorites))

这将为您提供user_id in the user_favorite如果用户已收藏该字段,None如果他们没有。

基本上,您正在编写一个子查询来从相关表中选择任意值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

布尔注释导致重复? 的相关文章

随机推荐