如何使用Django Orm创建临时布尔字段

时间:2018-08-20 19:43:24

标签: sql django postgresql django-models

图片我有以下型号:

class Product(models.Model):
    name = models.CharField(max_length=20)

class Receipt(models.Model):
    product = models.ForeignKey(Product)
    user = models.ForeignKey(User)

我有一个产品ID和用户的输入列表。我想查询每个产品,是否由该用户购买。请注意,我需要一个基于给定输入的所有现有产品的查询集,因为即使每个用户都没有购买该产品,我也需要其他字段,因此我无法使用Product.objects.filter(receipt__user=user)

那么我可以创建一个临时布尔字段来在单个查询中显示此属性吗?我正在使用Django 1.8和postgresql 9.3

更新要求:将产品分为两组。一个是由该特定用户购买的,另一个则不是。我认为任何给定的过滤器都无法实现这一点。这应该通过使用注释或F表达式创建一个新的临时字段来实现。

2 个答案:

答案 0 :(得分:1)

我认为,您需要 .annotate() 表达式

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

product_queryset = Product.objects.annotate(
    is_purchased=Case(
        When(receipt__user=current_user, then=Value('True')),
        default=Value('False')

    ))


如何访问带注释的字段?

product_queryset.first().is_purchased

答案 1 :(得分:0)

@JPG的答案。

我只是意识到除了条件表达式,还有另一种简单的方法。

仅使用prefetch_related将在两个查询中实现所有功能。尽管它是条件表达式的两倍,但它仍然是一个相当耗时的解决方案。

products = Product.objects.filter(id__in=[1,2,3,4,5]).prefetch_related ('receipt_set').all()

然后我们可以通过

在Python中检测该产品的用户
for p in products:
    print user in [receipt.user_id for receipt in p.purchase_set.all()]