Reputation: 53
The goal is to filter Fitness objects by specified SportType objects, i.e. all Fitness objects which contains at least one specified SportType object as foreignkey.
Here is my models and example:
class Fitness(models.Model):
name = models.Charfield(max_length=100)
class SportType(models.Model):
name = models.CharField(max_length=100)
class FitnessSportType(models.Model):
fitness = models.ForeignKey(Fitness, related_name='sport_type_set')
sport_type = models.ForeignKey(SportType, related_name='fitness_set')
f1 = Fitness.objects.create(name='foo')
f2 = Fitness.objects.create(name='bar')
f3 = Fitness.objects.create(name='goo')
s1 = SportType.objects.create(name='a')
s2 = SportType.objects.create(name='b')
s3 = SportType.objects.create(name='c')
FitnessSportType.objects.create(fitness=f1, sport_type=s1)
FitnessSportType.objects.create(fitness=f1, sport_type=s2)
FitnessSportType.objects.create(fitness=f2, sport_type=s1)
FitnessSportType.objects.create(fitness=f2, sport_type=s3)
FitnessSportType.objects.create(fitness=f3, sport_type=s2)
SOME_MAGIC_FUNCTION([s1, s3]) = [f1, f2]
P.S: sorry for bad English :)
Upvotes: 1
Views: 48
Reputation: 599956
You can improve this query by explicitly declaring FitnessSportType as the through table in the many-to-many relationship between Fitness and SportType:
class Fitness(models.Model):
...
sport_types = models.ManyToManyField('SportType', through='Fitness')
Now you can do:
Fitness.objects.filter(sport_types__in=[s1, s2])
If you don't have any other fields on FitnessSportType, there's no reason to declare it explicitly at all; remove it, and the through
attribute on the M2M, and the query will work exactly the same.
Upvotes: 2
Reputation: 6052
You can use double underscores to traverse relationships and __in
to test for multiple SportType
s.
results = Fitness.objects.filter(sport_type_set__sport_type__in=[s1, s2])
Upvotes: 2
Reputation: 6404
Try this
FitnessSportType.objects.filter(sport_type='a').values('fitness__name')
You will get all fittness name which sport_type
equal to a
Upvotes: 1