在Django中,如何过滤for循环中的_set?

dtcbnfnu  于 2023-01-27  发布在  Go
关注(0)|答案(1)|浏览(122)

我有这两种型号:

class Convocacao(models.Model):
  cursos = models.ForeignKey(Cursos)

class RegistroConvocacao(models.Model):
 convocacao = models.ForeignKey(Convocacao)

我从Convocacao得到一个特定的对象:

obj = get_object_or_404(
    Convocacao.objects.prefetch_related("cursos", "registroconvocacao_set"),
    pk=pk,
)

现在,当for循环通过obj.cursos运行时,我需要在循环内部过滤obj.registroconvocacao_set:

for curso in obj.cursos.all():
     obj.registroconvocacao_set.filter(...filters...)...

但是,在for循环的每次迭代中,obj.registroconvocacao_set.filter()都会对数据库进行新的查询,从而生成数千次对数据库的访问和重复的查询。
如何预取obj.registroconvocacao_set以避免这种情况?

42fyovps

42fyovps1#

你已经预取了对象,所以在Python中遍历所有对象,生成你想要的对象列表。

todo = []
for o in obj.registroconvocacao_set.all():
    if( rejection_condition): 
        continue
    if( acceptance_condition):
        todo.append(o)
        continue
    ...

for filtered_objects in todo:
    ...

简单的案例只是在循环中有一个简单的测试,来执行一个动作或者不执行:

for o in obj.registroconvocacao_set.all():
    if( condition): 
       ... #do stuff with o

或列表解析

todo = [ o for o in obj.registroconvocacao_set.all() if condition ]

是的,如果查询集能够识别出它们正在过滤的内容已经被预取,这样它们就可以在内部完成这一操作,而无需再次访问DB,那就太好了。但是它们没有,所以你必须自己编写代码·

相关问题