Sql Django按相关模型的字段进行筛选,并用该相关模型的另一个字段进行注释

Sql Django按相关模型的字段进行筛选,并用该相关模型的另一个字段进行注释,sql,django,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.Mod

假设我有这样一个模型:

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)
q = Intructor.objects.filter(Q(city__name=city) and Q(activityoffered__activity__name=activity) and Q(activityoffered__level__name = level))
Instructor.objects.anotate(min_price=Min(price)).filter(city=city).filter(activityoffered__activity = activity, activityoffered__level = level)
然而,我还想通过提供的活动的价格来注释讲师

我想得到一份提供初学者射箭的所有教练的名单,以及他们提供射箭的价格


最有效的方法是什么?我是否最好获取活动提供实例的查询集,然后从中构造它?

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

q = Intructor.objects.filter(Q(city=city) and Q(activityoffered__activity=activity) and Q(activityoffered__level = level))
此代码假定城市、活动提供的活动,。。。是一个相互尊重的对象城市、活动。。。。如果没有,您可以使用以下内容:

Instructor.objects..filter(city=city).filter(activityoffered__activity = activity, activityoffered__level = level)
q = Intructor.objects.filter(Q(city__name=city) and Q(activityoffered__activity__name=activity) and Q(activityoffered__level__name = level))
Instructor.objects.anotate(min_price=Min(price)).filter(city=city).filter(activityoffered__activity = activity, activityoffered__level = level)
如果要与参考价格进行比较:

这里我使用了queryset中字段的uu ltless属性

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))
您可以使用大于或小于或等于或大于或等于

anotate别忘了添加anotate、min或max模块 使用queryset,您可以执行以下操作:

Instructor.objects..filter(city=city).filter(activityoffered__activity = activity, activityoffered__level = level)
q = Intructor.objects.filter(Q(city__name=city) and Q(activityoffered__activity__name=activity) and Q(activityoffered__level__name = level))
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

谢谢你的回答。以我上面的射箭例子来说,这难道不是给了我一些做射箭并且在初学者水平上教东西的教练,而不是在初学者水平上教射箭的教练吗?我问题中的查询已经正确地完成了这一点,这是我正在努力解决的价格注释!可以可以给我15分钟!我再补充一个答案!若有,你们可以用我的答案,若并没有,其他的元素参考是什么来比较的???是的,初学者是级别的名称。假设我有两位导师。一个教初级射箭,一个教初级网球,一个教高级射箭。您的查询将使我得到两个讲师,而我只需要第一个。它也不能解决价格问题,我想你还不明白。我不想和价格比较,我想用价格来注释queryset。您的查询集也错误,它应该是讲师.objects.filtercity=city.filteractivityoffered\u_activity=activity,activityoffered\u_level=level