Reputation: 273
I am trying to reduce my complexity by doing the following. I am trying to get all the teachers in active classrooms.
teacher/models.py:
Teacher(models.Model):
name = models.CharField(max_length=300)
classroom/models.py:
Classroom(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('classroom_set',queryset=Classroom.objects.filter(status='Active'))
for teacher in teachers:
classrooms = teacher.all()
# run functions
By doing this I get teachers with classrooms. But it also returns teachers with no active classrooms(empty list) which I don't want. Because of this, I have to loop around thousands of teachers with empty classroom_set. Is there any way I can remove those teachers whose classroom_set is [ ]?
This is my original question - Django multiple queries with foreign keys
Thanks
Upvotes: 9
Views: 13234
Reputation: 477686
If you want all teachers with at least one related active class, you do not need to prefetch these, you can filter on the related objects, like:
Teacher.objects.filter(class__status='Active').distinct()
If you want to filter the classroom_set
as well, you need to combine filtering as well as .prefetch_related
:
from django.db.models import Prefetch
Teacher.objects.filter(
class__status='Active'
).prefetch_related(
Prefetch('class_set', queryset=Class.objects.filter(status='Active'))
).distinct()
Here we thus will filter like:
SELECT DISTINCT teacher.*
FROM teacher
JOIN class on class.teacher_id = teacher.id
WHERE class.status = 'Active'
Upvotes: 15