Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.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 在Django中两次使用filter()的有效方法_Python_Sql_Django_Postgresql - Fatal编程技术网

Python 在Django中两次使用filter()的有效方法

Python 在Django中两次使用filter()的有效方法,python,sql,django,postgresql,Python,Sql,Django,Postgresql,我对Django和Python比较陌生,但我还没有完全弄明白这一点 我基本上希望使用过滤器为大量用户查询数据库。然后我想对这部分用户进行一系列查询。因此,我认为最有效的方法是首先查询较大的过滤器参数,然后在该集合上进行单独的过滤器查询。在代码中,它看起来像这样 #Get the big groups of users, like all people with brown hair. group_of_users = Data.objects.filter(......) #Now get

我对Django和Python比较陌生,但我还没有完全弄明白这一点

我基本上希望使用过滤器为大量用户查询数据库。然后我想对这部分用户进行一系列查询。因此,我认为最有效的方法是首先查询较大的过滤器参数,然后在该集合上进行单独的过滤器查询。在代码中,它看起来像这样

#Get the big groups of users, like all people with brown hair.
group_of_users  = Data.objects.filter(......) 

#Now get all the people with brown hair and blue eyes, and then all with green eyes, etc.
for each haircolor :
  subset_of_group = group_of_users.filter(....) 
顺便说一下,这只是伪代码,我并不是那么无能。我认为这样会更有效,但如果消除第一个查询,只在for循环中获取查询集,似乎会更快(实际上是计时的)。 我担心这是因为当我先过滤,然后每次在for循环中过滤时,它实际上是对每个for循环执行两组过滤查询。所以说真的,做两倍于我想要的工作量。我认为缓存这一点无关紧要,因为第一个过滤器结果会被缓存,而且速度会更快,但我再次通过多个测试对其进行计时,单个过滤器会更快。有什么想法吗

编辑:
因此,似乎不可能查询一组数据,然后仅尝试进一步查询该组数据。相反,我应该查询一组数据,然后使用常规Python进一步解析该数据

您的方法完全正确,而且非常有效。查询集在被评估之前不会触及数据库,因此您可以添加任意多个过滤器,而数据库不会被触及。提供计算查询集的操作所需的所有信息。

筛选Django查询集不会执行任何数据库操作,直到您实际尝试访问结果。过滤只会将条件添加到查询集,然后在访问查询结果时使用这些条件生成最终查询


当您分配
用户组=Data.objects.filter(…)
时,不会从数据库检索任何数据;您只需要得到一个查询集,它知道您需要满足特定条件的记录(您提供给
Data.objects.filter
的筛选参数),但它不会预取那些实际用户。之后,当您分配
subset\u of_group=group\u of_users.filter(..)
时,您不会只过滤前一组用户,而只会向queryset添加更多条件;目前还没有从数据库中检索到任何数据。只有当您实际尝试访问查询集的结果时(例如,通过对查询集进行迭代,或通过对其进行切片,或通过访问其中的单个索引),查询集才会构建(通常)单个查询,该查询将仅检索满足您在查询集中积累的所有筛选条件的用户记录。它仍然需要过滤整个用户表以找到匹配的用户;它无法利用来自
组的
queryset的“先前检索到的”用户,因为此时实际上没有检索到任何内容。

正如garnertb ans lanzz所说,无论在何处使用
filter
功能,唯一重要的是计算查询的时间(请参阅)。我的猜测是,在您的测试中,您在代码中的某个地方对queryset进行求值,并且在测试中使用单独的过滤器调用进行更多求值

每当对查询集求值时,都会缓存其结果。但是,如果在queryset上使用另一种方法,例如
过滤器
排序,则不会保留此缓存。因此,您不能尝试对较大的集合求值,而在查询集上使用筛选来检索较小的集合,而不进行其他查询

如果您只有一小部分头发颜色,那么可以对每种头发颜色进行查询。但是,如果您有许多查询,那么查询的数量将对性能产生严重影响。在这种情况下,最好对要使用的全套用户进行查询,然后用python进行后续处理:

qs = Data.objects.filter(hair='brown')
objects = dict()
for obj in qs:
   objects.setdefault(obj.haircolour, []).append(obj)

for (k, v) in objects.items():
    print "Objects for colour '%s':" % k
    for obj in v:
        print "- %s" % obj

谢谢这就是我害怕的。那么,是否没有办法从本质上最小化我正在查看的数据库的大小?我想过滤一次,以获得一组较小的数据进行过滤,但我只是使用冗余参数进行过滤。这不是QuerySet的工作方式吗?这不是数据库的工作方式。如果您的第一个查询集确实从数据库中提取了实际记录,那么您将无法对该集应用任何进一步的筛选,因为筛选发生在数据库中,而不是在已经检索到应用程序中的一组数据中。您可以强制使用第一个查询集进行检索(例如,
group\u of_users=list(Data.objects.filter(…)
),但是
group\u of_users
将是一个简单的用户实例列表,您将无法对其使用查询集过滤。@lanzz理论上,这是可能的,django的方法可以过滤数据库已经获取的数据集。我相信这就是OP的要求。谢谢你的回答,这就是我所担心的。有没有办法过滤查询集,然后只过滤那组数据?或者这在QuerySet中是不可能的?好吧,正如我担心的那样,基本上没有办法查询一个大的数据集,然后只高效地查询那个小的数据集。相反,我应该研究查询一组数据,然后使用python进一步分割这些数据。如果我理解正确,请留下一个小评论。你过于复杂的
try:except-KeyError
语句可以简化为
objects.setdefault(obj.haircolour,[])。append(obj)
@lanzz啊,我喜欢这种构建dict的方法。更新了我的答案。谢谢