Django - 过滤 prefetch_related 查询集

Posted

技术标签:

【中文标题】Django - 过滤 prefetch_related 查询集【英文标题】:Django - Filter the prefetch_related queryset 【发布时间】:2019-03-16 08:35:12 【问题描述】:

我正在尝试通过执行以下操作来降低复杂性。我正在努力让所有老师都活跃在课堂上。

teacher/models.py:

Teacher(models.Model):
    name = models.CharField(max_length=300)


clas-s-room/models.py:

Clas-s-room(models.Model):
    name = models.CharField(max_length=300)
    teacher = models.ForeignKey(Teacher)
    students = models.ManyToManyField(Student)
    status = models.CharField(max_length=50)

admin/views.py

teachers = Teacher.objects.prefetch_related(Prefetch('clas-s-room_set',queryset=Clas-s-room.objects.filter(status='Active'))


for teacher in teachers:
    clas-s-rooms = teacher.all()
    # run functions

通过这样做,我得到了有教室的老师。但它也会返回没有我不想要的活动教室(空列表)的教师。正因为如此,我不得不用空的教室集循环数以千计的老师。有什么办法可以删除那些教室集为[]的老师吗?

这是我最初的问题 - Django multiple queries with foreign keys

谢谢

【问题讨论】:

如果老师有一个主动教室和一个被动教室怎么办? 你能提供这个模型吗? 这里的“教室”是什么?什么定义了课堂是否活跃? 不应该是Clas-s-room 而不是Class吗? @WillemVanOnsem 是的,我的错。 Guys Clas-s-room 和 Teacher 是两个不同的应用 【参考方案1】:

如果您希望所有教师至少有一个相关的活动类,则不需要预取这些,您可以过滤相关对象,例如:

Teacher.objects.filter(class__status='Active').distinct()

如果你想同时过滤clas-s-room_set,你需要结合过滤以及.prefetch_related

Teacher.objects.filter(
    class__status='Active'
).prefetch_related(
    Prefetch('class_set', queryset=Class.objects.filter(status='Active'))
).distinct()

在这里我们将过滤如下:

SELECT DISTINCT teacher.*
FROM teacher
JOIN class on class.teacher_id = teacher.id
WHERE class.status = 'Active'

【讨论】:

以上是关于Django - 过滤 prefetch_related 查询集的主要内容,如果未能解决你的问题,请参考以下文章

“模板语法错误:过滤器无效:”;基于 django 文档的自定义 django 模板过滤器损坏,但模板标签有效

Django 自定义过滤器

Django基础-过滤器

如何在 django 中按日期范围过滤记录?

Django:根据自定义函数过滤查询

Django template 过滤器