我正在努力做一些簡單的事情。我有Item物件,用戶可以將它們標記為收藏夾。由于這些專案不屬于用戶,我決定使用 ManyToMany 之間User和Item記錄最喜歡的關系。如果用戶在favoriters專案欄位中,則表示用戶收藏了它。
然后,當我為特定用戶檢索物件時,我想注釋每個專案以指定用戶是否喜歡它。我為此制定了add_is_favorite_for()方法。
這是(簡化的)代碼:
class ItemQuerySet(query.QuerySet):
def add_is_favorite_for(self, user):
"""add a boolean to know if the item is favorited by the given user"""
condition = Q(favoriters=user)
return self.annotate(is_favorite=ExpressionWrapper(condition, output_field=BooleanField()))
class Item(models.Model):
objects = Manager.from_queryset(ItemQuerySet)()
favoriters = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True)
這不像預期的那樣作業,似乎 Django 為喜歡該專案的每個用戶添加了一個專案。它會導致瘋狂的事情,例如:
Item.objects.count() # 10
Item.objects.add_is_favorite_for(some_user).count() # 16 -> how the hell an annotation can return more results than initial queryset?
我在這里遺漏了一些東西......
uj5u.com熱心網友回復:
您可以更改注釋中的條件以使用子查詢,獲取用戶收藏的所有 Item,然后測驗以查看 Item 的 id 是否在子查詢中。
這應該會消除您的重復問題:
def add_is_favorite_for(self, user):
return self.annotate(is_favorite=ExpressionWrapper(
Q(id__in=Item.objects.filter(favoriters=user).values('id')),
output_field=BooleanField()
))
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/389607.html
標籤:Python 姜戈 django 模型 django-queryset
上一篇:在Django中過濾多對多關系
