Home > database >  Django exclude from queryset if all attributes of the set not match
Django exclude from queryset if all attributes of the set not match

Time:02-16

I have 2 models Course and Class

model

I'm trying to exclude the courses where ALL his classes vacancies are 0, but this query is excluding the course if only one of the class vacancies is 0.

 courses = Course.objects.all().exclude(class_set__vacancies=0)

Classes:

enter image description here

CodePudding user response:

If you are trying to get a Queryset containing a list of all the courses where there is at least one vacancy in any associated class, try this:

courses = Course.objects.filter(class__vacancies__gte = 1).distinct()

You don't need _set in your filter() argument; when the call is made to the database, its joining the Course and Class tables anyway.

As I think you know, but I'll point out for the sake of clarity, __vacancies is Django's shorthand way of representing a field in a related table; in this case, the related table is the Class table, and the related field is vacancies.

The __gte in .filter(class__vacancies__gte = 1) is "greater than or equal to", so basically this function gets a list of all the Course-Class combinations where there is at least one vacancy in the class, then returns just the Course object.

If you had a Course with two Classes, and both Classes had vacancies, Course.objects.filter(class__vacancies__gte = 1) would return duplicate Courses. I'm assuming you just want a list of the Courses with open classes, and thus duplicates are undesirable. In order to remove the duplicates, you need to include .distinct().

.distinct() can be tricky though, depending on your specific use case. See the Django docs at https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.distinct

  • Related