【问题标题】:Django exclude queryset __in for *every* item in listDjango为列表中的*每个*项目排除查询集__in
【发布时间】:2018-10-31 22:52:15
【问题描述】:

这与Django filter queryset __in for *every* item in listDjango filter queryset __in for *every* item in list (2.0) 有点不同 给定以下模型:

class Product(BaseModel):
    ''' whatever '''

class Customer(BaseModel):
    blacklist = models.ManyToManyField(Product, blank=True)

class Advisory(BaseModel):
    product_names = models.ManyToManyField(Product)

客户在哪里维护其不感兴趣的产品列表。如何获取给定客户的建议列表?

假设我的数据库中有这些:

#   Advisory 1 (should be included as Product 1 isn't in the customers blacklist)
#       product_names
#           Product 1
#           Product 2
#           Product 3
#   Advisory 2 (should be excluded)
#       product_names
#           Product 2
#           Product 3
#   Customer 1
#       blacklist
#           Product 2
#           Product 3
#           Product 4
#           Product 5

如果我使用这样的查询集:

queryset = Advisory.objects.all()
blacklist = Customer.blacklist.all()
queryset = queryset.exclude(product_names__in=blacklist).distinct()

它将排除建议 1 和建议 2,因为产品 2 和 3 存在于客户黑名单中

【问题讨论】:

  • 所以您只希望所有具有至少一个product但不在blacklist中的建议?
  • 是的,没错。
  • 基本上你需要的是一个NOT IN,这在Django中显然是缺少的。 .exclude 实际上等于NOT IN,因为它意味着NOT IN 在整个关系中。

标签: python django django-models django-queryset


【解决方案1】:

我分两步解决了这个问题:

# Get the queryset with all advisories
queryset = Advisory.objects.all()
# Find the products the customer doesn't care about
blacklist = Customer.objects.get(pk=customer_id).blacklist.all()
# Build a whitelist of products excluding the blacklist from the customer
whitelist = Product.objects.all().exclude(id__in=blacklist)
# And filter the queryset with the new whitelist
queryset = queryset.filter(product_names__in=whitelist).distinct()

【讨论】:

    猜你喜欢
    • 2017-11-07
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    • 2012-07-07
    • 1970-01-01
    • 2015-12-30
    • 2011-11-13
    • 1970-01-01
    相关资源
    最近更新 更多