正确的方法来注释被收藏的物品

时间:2014-06-11 15:17:05

标签: python django django-models

鉴于此模型:

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'))

这是最好的方法吗?

2 个答案:

答案 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