如何仅编写一个Django ORM查询?

时间:2019-08-21 06:44:20

标签: django orm

目标是通过指定的SportType对象(即,至少包含一个指定SportType对象作为外键的所有Fitness对象)过滤Fitness对象。

这是我的模型和示例:

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:对不起,英语不好:)

3 个答案:

答案 0 :(得分:2)

您可以使用双下划线来遍历关系,并可以使用__in测试多个SportType

results = Fitness.objects.filter(sport_type_set__sport_type__in=[s1, s2])

答案 1 :(得分:2)

您可以通过在Fitness与SportType之间的多对多关系中显式声明FitnessSportType作为通过表来改进此查询:

class Fitness(models.Model):
    ...
    sport_types = models.ManyToManyField('SportType', through='Fitness')

现在您可以这样做:

Fitness.objects.filter(sport_types__in=[s1, s2])

如果FitnessSportType上没有其他任何字段,则完全没有理由明确声明它。删除它,并删除M2M上的through属性,查询将完全相同。

答案 2 :(得分:1)

尝试一下

XMLHttpRequest

您将获得FitnessSportType.objects.filter(sport_type='a').values('fitness__name') 等于sport_type的所有健身名称