Python Django中使用RawQuerySet的惰性查询

Python Django中使用RawQuerySet的惰性查询,python,django,Python,Django,我在理解Django中原始查询的行为时遇到问题。问题在于使用RawQuerySet时对数据库的查询数量。看起来每次我使用RawQuerySet时都会发送新的数据库查询。例如,使用此代码: reviews = Reviews.objects.raw('select * from reviews rv [...]') count = len(list(reviews)) avg_rating = 0.0 if count > 0: for r

我在理解Django中原始查询的行为时遇到问题。问题在于使用RawQuerySet时对数据库的查询数量。看起来每次我使用RawQuerySet时都会发送新的数据库查询。例如,使用此代码:

    reviews = Reviews.objects.raw('select * from reviews rv [...]')

    count = len(list(reviews))
    avg_rating = 0.0

    if count > 0:
        for r in reviews:
            avg_rating = avg_rating + r.stars       
            avg_rating = avg_rating/float(count)

    avg_rating = avg_rating/float(count)

每次使用“reviews”都会生成新的、相同的查询。为什么罗克丽塞特这么懒?在我看来,一旦有人决定使用原始查询,他就不需要Django提供额外的“帮助”。我错过什么了吗?在这种情况下,有没有办法只进行一次查询?是的,我决定将Reviews.objects.raw()强制转换为list(),这很有帮助,但我仍然不明白为什么要这样做。

问题来自您的
列表(Reviews)
表达式-这迫使RawQuerySet以某种方式尝试从初始查询构建完整的模型实例(可能不是以最有效的方式,但这是另一种情况)。如果没有这一行,并且假设您没有访问相关对象,那么只会进行一次查询,正如您在这段代码中所看到的:

>>> from survey.models import Question
>>> from django.db import connection
>>> import pprint
>>> connection.queries
[]
>>> raw = Question.objects.raw("select * from survey_question")
>>> for q in raw:
...     print q.id
... 
1
2
3
4
>>> connection.queries
[{'time': '0.000', 'sql': 'select * from survey_question'}]
>>> list(raw)
[<Question: Survey Essai1 (root) question #1 - Depuis combien de temps programmez vous ?>, <Question: Survey Essai1 (root) question #2 - Comment avez vous débuté ?>, <Question: Survey Essai1 (root) question #3 - Quel est votre niveau de formation>, <Question: Survey Essai1 (root) question #4 - Cette formation porte-t-elle sur l'informatique ?>]
>>> pprint.pprint(connection.queries)
[{'sql': 'select * from survey_question', 'time': '0.000'},
 {'sql': 'select * from survey_question', 'time': '0.000'},
 {'sql': 'SELECT `survey_survey`.`id`, `survey_survey`.`user_id`, `survey_survey`.`title`, `survey_survey`.`notes`, `survey_survey`.`description`, `survey_survey`.`instructions`, `survey_survey`.`date_created`, `survey_survey`.`starts_on`, `survey_survey`.`ends_on` FROM `survey_survey` WHERE `survey_survey`.`id` = 1 ',
  'time': '0.001'},
 {'sql': 'SELECT `auth_user`.`id`, `auth_user`.`username`, `auth_user`.`first_name`, `auth_user`.`last_name`, `auth_user`.`email`, `auth_user`.`password`, `auth_user`.`is_staff`, `auth_user`.`is_active`, `auth_user`.`is_superuser`, `auth_user`.`last_login`, `auth_user`.`date_joined` FROM `auth_user` WHERE `auth_user`.`id` = 1 ',
  'time': '0.001'},
 {'sql': 'SELECT `survey_survey`.`id`, `survey_survey`.`user_id`, `survey_survey`.`title`, `survey_survey`.`notes`, `survey_survey`.`description`, `survey_survey`.`instructions`, `survey_survey`.`date_created`, `survey_survey`.`starts_on`, `survey_survey`.`ends_on` FROM `survey_survey` WHERE `survey_survey`.`id` = 1 ',
  'time': '0.000'},
 {'sql': 'SELECT `auth_user`.`id`, `auth_user`.`username`, `auth_user`.`first_name`, `auth_user`.`last_name`, `auth_user`.`email`, `auth_user`.`password`, `auth_user`.`is_staff`, `auth_user`.`is_active`, `auth_user`.`is_superuser`, `auth_user`.`last_login`, `auth_user`.`date_joined` FROM `auth_user` WHERE `auth_user`.`id` = 1 ',
  'time': '0.000'},
 {'sql': 'SELECT `survey_survey`.`id`, `survey_survey`.`user_id`, `survey_survey`.`title`, `survey_survey`.`notes`, `survey_survey`.`description`, `survey_survey`.`instructions`, `survey_survey`.`date_created`, `survey_survey`.`starts_on`, `survey_survey`.`ends_on` FROM `survey_survey` WHERE `survey_survey`.`id` = 1 ',
  'time': '0.000'},
 {'sql': 'SELECT `auth_user`.`id`, `auth_user`.`username`, `auth_user`.`first_name`, `auth_user`.`last_name`, `auth_user`.`email`, `auth_user`.`password`, `auth_user`.`is_staff`, `auth_user`.`is_active`, `auth_user`.`is_superuser`, `auth_user`.`last_login`, `auth_user`.`date_joined` FROM `auth_user` WHERE `auth_user`.`id` = 1 ',
  'time': '0.000'},
 {'sql': 'SELECT `survey_survey`.`id`, `survey_survey`.`user_id`, `survey_survey`.`title`, `survey_survey`.`notes`, `survey_survey`.`description`, `survey_survey`.`instructions`, `survey_survey`.`date_created`, `survey_survey`.`starts_on`, `survey_survey`.`ends_on` FROM `survey_survey` WHERE `survey_survey`.`id` = 1 ',
  'time': '0.000'},
 {'sql': 'SELECT `auth_user`.`id`, `auth_user`.`username`, `auth_user`.`first_name`, `auth_user`.`last_name`, `auth_user`.`email`, `auth_user`.`password`, `auth_user`.`is_staff`, `auth_user`.`is_active`, `auth_user`.`is_superuser`, `auth_user`.`last_login`, `auth_user`.`date_joined` FROM `auth_user` WHERE `auth_user`.`id` = 1 ',
  'time': '0.000'}]
>>> 
或者使用ORM的聚合函数(cf):

select avg(stars) from reviews;
>>> from django.db.models import Avg
>>> Book.objects.all().aggregate(Avg('price'))