鉴于此模型:
class Piece(models.Model):
name = models.CharField(max_length=50)
description = models.TextField(blank=True, null=True)
favorited = models.ManyToManyField(User, through='FavoritedPieces', blank=True, null=True)
class FavoritedPieces(models.Model):
user = models.ForeignKey(User)
piece = models.ForeignKey(Piece)
created_at = models.DateTimeField(auto_now_add=True)
我怎样才能获得所有带有额外字段的片段列表,“收藏”,是真还是假?这取决于用户是否将其标记为收藏。
实施例: 我有一个10件的清单。用户收藏了其中3个。当我打印列表时,如果该片段已被该用户收藏,我还需要打印。
List: [ <Piece1: name.. description.. favorited:False>,
<Piece2: name.. description.. favorited:False>,
<Piece3: name.. description.. favorited:True>,
]
我不想制作像这个问题的新项目列表:How to compare lists and get total matching items count
我想要类似的东西:MyModel.objects.annotate(total_likes=Sum('piece__total_likes'))
这是最好的方法吗?
答案 0 :(得分:1)
我建议做这样的事情:
pieces = Piece.objects.annotate(favorites_count=Count('FavoritedPieces'))
然后,当您查看结果时,您可以执行以下操作:
if piece.favorites_count > 0:
我知道它并不完全是你想要的,但我觉得它很简单。
答案 1 :(得分:1)
使用extra()
:
Piece.objects.extra(select={'was_favorited': '''
SELECT
CASE WHEN id IS NULL THEN false ELSE true END
FROM appname_favoritedpieces
WHERE appname_favoritedpieces.piece_id = appname_piece.id
'''})
这会为您提供额外的字段'was_favorited'
。但是,如果你所做的只是检查这件作品是否被收藏,那么有更简单的方法可以做到这一点:
测试字段本身:
for p in Piece.objects.all():
if p.favorited:
pass # do something if the Piece was favorited
如果您确实需要该布尔值,请添加属性was_favorited()
:
class Piece(models.Model):
...
@property
def was_favorited(self):
return true if self.favorited else false
# then you can call this property on Piece objects:
>>> Piece.objects.get(name="No one's favorite").was_favorited
False