【问题标题】:How to create a temp boolean field with Django orm如何使用 Django orm 创建临时布尔字段
【发布时间】:2019-01-26 23:38:02
【问题描述】:

图片我有以下型号:

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 表达式创建一个新的临时字段来实现。

【问题讨论】:

  • 您的问题不清楚。您要过滤什么属性?
  • @Mint 将产品分成两组。一个是这个特定用户购买的,另一个不是。我认为任何给定的过滤器都不能实现这一点。这应该通过 annotate 或 F 表达式创建一个新的临时字段来实现。

标签: sql django postgresql django-models


【解决方案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

【讨论】:

    【解决方案2】:

    感谢@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()]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-23
      • 1970-01-01
      • 2013-12-06
      • 1970-01-01
      • 2017-06-14
      • 2020-04-11
      • 2012-03-24
      相关资源
      最近更新 更多