【问题标题】:How to filter queryset based on related objects if it contains data in django如果查询集包含django中的数据,如何根据相关对象过滤查询集
【发布时间】:2019-10-08 14:02:25
【问题描述】:

如果仅与其父对象相关的子对象具有数据,我想过滤并仅获取与其相关对象数据相关的那些数据。例如: 我有以下型号:

class Collection(models.Model):
    date_of_collection=models.DateField()

class Product(models.Model):
    name=models.CharField(max_length=100)
    collection = models.ForeignKey(Collection)

class Price(models.Model):
    price = models.FloatField()
    products = models.ForeignKey(Products, on_delete=models.CASCADE)

我有与模型相关的数据:

Collection:
+----+--------------------+
| id | date_of_collection |
+----+--------------------+
|  1 | 2019-01-17         |
|  2 | 2019-01-30         |
|  3 | 2019-02-01         |
|  4 | 2019-02-02         |
+----+--------------------+

Products:

 +----+--------------------------------+
 | id | name           | collection    |
 +----+--------------------------------+
 |  1 | product 1      | 3             |
 |  2 | product 2      | 1             |
 |  3 | product 3      | 1             |
 |  4 | product 4      | 4             |
 +----+--------------------------------+

Price:

| id     | price            | product               |
+--------+------------------+-----------------------+
| 1      | 10.00            | 1                     |
| 2      | 20.00            | 1                     |
| 3      | 12.00            | 3                     |
+--------+------------------+-----------------------+

这里我的价格仅与 13 产品相关,所以我只想要那些基于查询集的产品,我只想根据特定的 date_of_collection 进行过滤。

我尝试了以下查询集:

collection_month = Collection.objects.filter(date_of_collection__month=2)
product = Product.objects.filter(collection_id__in=collection_month).exclude(price_set__price=None)

是我做的方式还是下一个方式..它有时会产生不好的结果。我该怎么做。

【问题讨论】:

    标签: python django django-2.0


    【解决方案1】:

    你已经很接近了。
    您不应该将 collection_id 与实际收藏项目进行比较 - 您可以传递 collection__in=collection_month
    可以直接排除不带priceprice__isnull=True的产品

    此查询将使用子查询 (WHERE):

    collection_month = Collection.objects.filter(date_of_collection__month=2)
    products = Product.objects.filter(collection__in=collection_month).exclude(price__isnull=True)
    

    此查询将使用INNER JOIN,即rumored to be faster

    products = Product.objects.filter(collection__date_of_collection__month=2).exclude(price__isnull=True)
    

    【讨论】:

    • 感谢您的回复,我的数据库有一些条件确实需要collection__in 来检查数据。我希望.exclude(price__isnull=True 不起作用我们应该使用price_set__price__isnull=True 否则我们会得到django.core.exceptions.FieldError
    • @dipbazz 你真的检查过结果吗?它在我这边工作得很好。我可以将我的单元测试发送给你,表明它正在工作。
    • 它也对我有用,但问题是我必须使用 related_name__fields 来查找其相关对象。我只是无法直接从父对象访问子对象的字段。
    • @dipbazz 你能举个例子说明在什么查询中你不能从父对象访问子对象的字段?你想获取什么?
    • 因为我在价格模型的外键字段中设置了我的related_name,所以我的related_query_name 将默认为related_name 的值,如documentaion of django 中所述所以,我必须使用相关名称而不是查找中的模型名称。
    猜你喜欢
    • 2016-01-08
    • 2022-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 2019-07-12
    相关资源
    最近更新 更多