Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 查询Q()未按';集合包含';对于Django中的相关字段?_Python_Sql_Django - Fatal编程技术网

Python 查询Q()未按';集合包含';对于Django中的相关字段?

Python 查询Q()未按';集合包含';对于Django中的相关字段?,python,sql,django,Python,Sql,Django,假设我们有一篮子水果。如何筛选出包含给定篮子中所有水果的篮子 在本文件中 “in”方法似乎将返回包含给定水果的任何篮子。 是否有任何“set_contains”方法用于过滤?例如Basket.objects.filter(水果集\u containsAll=水果集) 编辑:我发现Q()未按预期工作。我将在这里发布测试: class Basket(models.Model): weight = models.FloatField(default=1) class Fruitname(mod

假设我们有一篮子水果。如何筛选出包含给定篮子中所有水果的篮子

在本文件中 “in”方法似乎将返回包含给定水果的任何篮子。 是否有任何“set_contains”方法用于过滤?例如Basket.objects.filter(水果集\u containsAll=水果集)

编辑:我发现Q()未按预期工作。我将在这里发布测试:

class Basket(models.Model):
    weight = models.FloatField(default=1)
class Fruitname(models.Model):
    name = models.CharField(max_length=32)
class Fruit(models.Model):
    ofkind = models.ForeignKey(Fruitname, on_delete=models.CASCADE)  
    inbasket = models.ForeignKey(Basket, on_delete=models.CASCADE)  
    weight = models.FloatField(default=1)
数据库设置为1个篮子中的“苹果”,2个篮子中的“梨”,3个篮子中的“香蕉”:

print Basket.objects.all()
print Fruitname.objects.all()
[<Basket: id 31 has 4 fruits 
    1. id - 53 apple(28), weight 1.00
    2. id - 54 apple(28), weight 2.00
    3. id - 55 apple(28), weight 3.00
    4. id - 62 banana(30), weight 10.00
>, <Basket: id 32 has 2 fruits 
    1. id - 56 pear(29), weight 4.00
    2. id - 57 banana(30), weight 5.00
>, <Basket: id 33 has 4 fruits 
    1. id - 58 pear(29), weight 6.00
    2. id - 59 banana(30), weight 7.00
    3. id - 60 pear(29), weight 8.00
    4. id - 61 pear(29), weight 9.00
>]
[<Fruitname: apple(28)>, <Fruitname: pear(29)>, <Fruitname: banana(30)>]
同样地

print Basket.objects.filter(Q(fruit__ofkind__name__in=['banana'])&Q(fruit__ofkind__name__in=['pear'])).distinct()
[]
这里是我如何使用“in”进行过滤的,它不是我所需要的,应该是一个空集

print Basket.objects.filter(Q(fruit__ofkind__name__in=['apple','pear'])).distinct()
[<Basket: id 31 has 4 fruits 
    1. id - 53 apple(28), weight 1.00
    2. id - 54 apple(28), weight 2.00
    3. id - 55 apple(28), weight 3.00
    4. id - 62 banana(30), weight 10.00
>, <Basket: id 32 has 2 fruits 
    1. id - 56 pear(29), weight 4.00
    2. id - 57 banana(30), weight 5.00
>, <Basket: id 33 has 4 fruits 
    1. id - 58 pear(29), weight 6.00
    2. id - 59 banana(30), weight 7.00
    3. id - 60 pear(29), weight 8.00
    4. id - 61 pear(29), weight 9.00
>]
print Basket.objects.filter(Q(种类的水果名称=['apple','pear']).distinct()
[, ]
正常工作的唯一方法是使用过滤器链接:

Basket.objects.filter(fruit__ofkind__name__in=['apple']).filter(fruit__ofkind__name__in=['banana']).distinct()
[<Basket: id 31 has 4 fruits 
    1. id - 53 apple(28), weight 1.00
    2. id - 54 apple(28), weight 2.00
    3. id - 55 apple(28), weight 3.00
    4. id - 62 banana(30), weight 10.00
>]
Basket.objects.filter(水果种类名称中=['apple'])。filter(水果种类名称中=['banana'])。distinct()
[]
这些代码使用Django 1.9.4进行测试
有什么解释吗?我将暂时撤销已被接受的答案

要获得一个包含所有可用
水果
实例的
篮子
,您可以执行以下操作:

from django.db.models import Count

# first get all PKs of fruits
fruit_pk_list = Fruit.objects.value_list('id', flat=True)

# Then get filter the basket with all fruits using annotate and Count
baskets = Basket.objects.annotate(
    num_fruit=Count('fruit')).filter(num_fruit=len(fruit_pk_list))

要获得一个包含所有可用
水果
实例的
篮子
,可以执行以下操作:

from django.db.models import Count

# first get all PKs of fruits
fruit_pk_list = Fruit.objects.value_list('id', flat=True)

# Then get filter the basket with all fruits using annotate and Count
baskets = Basket.objects.annotate(
    num_fruit=Count('fruit')).filter(num_fruit=len(fruit_pk_list))

不确定这是否是最有效的方法,但至少应该转化为一个(大的、丑陋的、嵌套的)sql事务(一旦计算了最终的
baskets
queryset):

可以尝试一种更优雅(也可能更高效)的方法,如下所示:使用
Q
对象组合查询(基于Dave Webb的):


不确定这是否是最有效的方法,但至少应该转化为一个(大的、丑陋的、嵌套的)sql事务(一旦计算了最终的
baskets
queryset):

可以尝试一种更优雅(也可能更高效)的方法,如下所示:使用
Q
对象组合查询(基于Dave Webb的):


通过打印Q&operations的原始SQL,我找到了Q如此工作的原因

from django.db import connection
print connection.queries
u'SELECT DISTINCT "market_basket"."id", "market_basket"."weight" FROM "market_basket" INNER JOIN "market_fruit" ON ("market_basket"."id" = "market_fruit"."inbasket_id") INNER JOIN "market_fruitname" ON ("market_fruit"."ofkind_id" = "market_fruitname"."id") WHERE ("market_fruitname"."name" IN (\'apple\') AND "market_fruitname"."name" IN (\'banana\')) LIMIT 21'
关键问题是当在单个筛选器中使用查询时,在单个条件下不会满足WHERE子句。它实际上是在寻找一个水果名同时在['apple']和['banana']中,这是不可能的。需要的是找到(水果名为“苹果”的水果)或(水果名为“香蕉”的水果)


目前唯一可行的解决方案是链式过滤器

通过打印Q&operations的原始SQL,我找到了Q如此工作的原因

from django.db import connection
print connection.queries
u'SELECT DISTINCT "market_basket"."id", "market_basket"."weight" FROM "market_basket" INNER JOIN "market_fruit" ON ("market_basket"."id" = "market_fruit"."inbasket_id") INNER JOIN "market_fruitname" ON ("market_fruit"."ofkind_id" = "market_fruitname"."id") WHERE ("market_fruitname"."name" IN (\'apple\') AND "market_fruitname"."name" IN (\'banana\')) LIMIT 21'
关键问题是当在单个筛选器中使用查询时,在单个条件下不会满足WHERE子句。它实际上是在寻找一个水果名同时在['apple']和['banana']中,这是不可能的。需要的是找到(水果名为“苹果”的水果)或(水果名为“香蕉”的水果)



目前唯一可行的解决方案是链式过滤器

by包含所有给定的水果,您指的是名称吗?我的意思是,你有什么,水果实例还是名称?请注意,如果你使用的是postgres db,那么有一个数组字段包含你描述的操作,名为
contains
。可能不适合您,因为您似乎需要一个对象数组,但是对于一个基本类型数组来说,这是一个不错的选择@levi,比如说给定一个篮子,找到所有其他篮子,其中至少包含相同种类的水果。这就像是basket.fruit_set.all()@serg,这个操作似乎是特定于数据库实现的?我想在如何用Django编写代码方面,性能不会有太大差别。这取决于数据库。如果包含所有给定的水果,您是否引用名称?我的意思是,你有什么,水果实例还是名称?请注意,如果你使用的是postgres db,那么有一个数组字段包含你描述的操作,名为
contains
。可能不适合您,因为您似乎需要一个对象数组,但是对于一个基本类型数组来说,这是一个不错的选择@levi,比如说给定一个篮子,找到所有其他篮子,其中至少包含相同种类的水果。这就像是basket.fruit_set.all()@serg,这个操作似乎是特定于数据库实现的?我想在如何用Django编写代码方面,性能不会有太大差别。这取决于数据库。不仅有相同数量的水果,而且有给定ID的所有指定水果。它过滤水果数量等于模型中所有水果数量的篮子。必须试着运行它吗?我想我的问题有些误解。我的意思是给定所有水果的子集,在子集中找到一个包含这些水果的篮子。我的意思不是像在Fruit.objects.all()中那样的所有水果,而是在
id\u的
filter中向
Basket
添加一个过滤器。。类似于
.filter(id\uu in=fruit\u pk\u list)
这将首先查找与水果数量匹配的篮子,然后检查水果是否与提供的id匹配。PS:
水果pk列表
这里是您选择和筛选的水果pk列表,不是全部。我知道中的id。但它将返回包含水果列表中任何给定id的所有篮子。我想要包含所有给定水果ID的篮子。不仅要有相同数量的水果,还要有具有给定ID的所有指定水果。它会过滤水果数量等于模型中所有水果数量的篮子。必须试着运行它吗?我想我的问题有些误解。我的意思是给定所有水果的子集,在子集中找到一个包含这些水果的篮子。我的意思不是像在Fruit.objects.all()中那样的所有水果,而是用
id\u in
filt向
Basket
添加一个过滤器
from django.db import connection
print connection.queries
u'SELECT DISTINCT "market_basket"."id", "market_basket"."weight" FROM "market_basket" INNER JOIN "market_fruit" ON ("market_basket"."id" = "market_fruit"."inbasket_id") INNER JOIN "market_fruitname" ON ("market_fruit"."ofkind_id" = "market_fruitname"."id") WHERE ("market_fruitname"."name" IN (\'apple\') AND "market_fruitname"."name" IN (\'banana\')) LIMIT 21'