【问题标题】:Django query to retrieve an initial queryset with subsequent queries on that querysetDjango 查询以检索初始查询集以及对该查询集的后续查询
【发布时间】:2012-10-04 09:42:08
【问题描述】:

对于此代码:

people_pool = People.objects.filter(last_name__in = last_names)
for first_name in first_names:
    for person in people_pool.filter(first_name = first_name):
       # do something with each person. 

我对 django 查询集的理解是,在您“需要”数据之前,实际上不会执行查询,因此可以优化链式查询集。但是,如果我没记错的话,这似乎对我不利。将执行的第一个查询基本上相当于:

People.objects.filter(last_name__in = last_names, first_name = first_name) # for the first first_name in first_names

并且需要为每个名字查询数据库。如果是这种情况,让 Django 实际检索 people_pool 并在检索到的 python 对象上运行后续过滤器的正确方法是什么,让数据库不理会?

【问题讨论】:

  • 你想达到什么目的?你可能想看看select_related
  • 我不想获取相关模型的任何属性。只是试图访问人员的直接字段,但希望通过由 python 执行过滤而不是作为单独的查询来以某种方式限制运行的查询数量。

标签: django django-queryset


【解决方案1】:

为了不对每个名字进行 db 查询,唯一的方法是在 Python 中进行实际过滤:

people_pool = People.objects.filter(last_name__in = last_names)
people = {}

for person in people_pool:
    first_name = person.first_name
    if first_name in first_names:
        if not first_name in people:
            people[first_name] = []
        people[first_name].append(person)

for first_name, people_first_name in people.items():
    for person in people_first_name:
        # do something with each person

如果你愿意,你也可以在第一个循环中做一些事情(for person in people_pool)。我只是在dict 中添加人员,但这一步不是必需的。

【讨论】:

  • 出于某种原因,我的印象是,如果您已经有一个缓存的查询集,然后进一步过滤该查询集,它就不必在数据库上运行另一个查询。我弄错了吗?
  • 是的。查询集缓存实际的查询参数,以便稍后您可以修改它们。它不会缓存实际的查询(嗯,它会缓存但仅在您第一次从查询集中获取对象之后)。 docs.djangoproject.com/en/dev/topics/db/queries/…
  • 确实,我弄错了。感谢您让我走上正确的道路。另请参阅seeknuance.com/2010/12/10/…
猜你喜欢
  • 2017-12-26
  • 2013-02-01
  • 2020-11-22
  • 2017-08-23
  • 1970-01-01
  • 2018-11-18
  • 2012-04-14
  • 2012-01-04
  • 2020-10-26
相关资源
最近更新 更多