Django按相关模型的字段进行过滤,并使用该相关模型的另一个字段进行注释

时间:2015-08-29 19:06:55

标签: sql django

说我有一个类似的模型:

class City(models.Model):
    name = models.CharField()

class Instructor(models.Model):
    name = models.CharField()
    town = models.ForeignKey(City)

class Activity(models.Model):
    name = models.CharField()

class Level(models.Model):
    name = models.CharField()

class ActivityOffered(models.Model):
    instructor = models.ForeignKey(Instructor)
    activity = models.ForeignKey(Activity)
    level = models.ForeignKey(Level)
    price = models.IntegerField()

鉴于一个城市,一个活动和水平,我想过那些有相关活动提供该活动和水平的人过滤那个城市的教师。我想我可以这样做:

Instructor.objects..filter(city=city).filter(activityoffered__activity = activity, activityoffered__level = level)

但是,我还想通过提供的活动的价格来注释教师。

E.g。我想获得一份提供初学者射箭的所有教练的清单以及他们提供的价格。

最有效的方法是什么?我最好获得一个活动提供实例的查询集,然后从那个构建它吗?

1 个答案:

答案 0 :(得分:0)

您可以使用Q对象过滤您这样的查询! (别忘了导入Q)

q = Intructor.objects.filter(Q(city=city) and Q(activityoffered__activity=activity) and Q(activityoffered__level = level))

此代码假设city,activityoffered__activity,...是一个相应的对象城市,活动,....如果不是,你可以使用这样的东西:

q = Intructor.objects.filter(Q(city__name=city) and Q(activityoffered__activity__name=activity) and Q(activityoffered__level__name = level))

如果您想与价格参考进行比较:

这里我使用了queryset

中字段的__lt(小于)属性
q = Intructor.objects.filter(Q(city__name=city) and Q(activityoffered__activity__name=activity) and Q(activityoffered__level__name = level) and Q(price__lt=price))

你可以使用__gt(大于)或__lte(小于或等于)或__gte(大于或等于)。

anotate(不要忘记添加anotate,min或max模块) 使用您的查询集,您可以执行以下操作:

Instructor.objects.anotate(min_price=Min(price)).filter(city=city).filter(activityoffered__activity = activity, activityoffered__level = level)

与Max你有类似的东西!

Instructor.objects.anotate(max_price=Max(price)).filter(city=city).filter(activityoffered__activity = activity, activityoffered__level = level)

如果你想知道价格,你就可以做到这一点:

q = Instructor.objects.filter(city=city).filter(activityoffered__activity = activity, activityoffered__level = level)
for i in q:
# some code
i.price

一切