【问题标题】:Django filter by field of related model and annotate with another field of that related modelDjango 按相关模型的字段过滤并使用该相关模型的另一个字段进行注释
【发布时间】:2015-08-29 19:06:55
【问题描述】:

假设我有这样的模型:

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)

但是,我还想用所提供活动的价格来注释讲师。

例如我想获取所有提供初学者射箭的教练的名单以及他们提供的价格。

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

【问题讨论】:

    标签: sql django


    【解决方案1】:

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

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

    此代码假设 city, activityoffered__activity,... 是一个相应的对象 city, activity, .... 如果不是,您可以使用如下内容:

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

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

    这里我使用了查询集中字段的__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(大于或等于)。

    注释(不要忘记添加注释,最小或最大模块) 使用您的查询集,您可以执行以下操作:

    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
    

    全部

    【讨论】:

    • 感谢您的回答。使用我上面的射箭示例,这不会给我提供射箭并教初学者水平的教练,而不是教初学者射箭的教练吗?我的问题中的查询已经正确完成了这一点,它是我正在努力解决的价格注释。
    • 啊啊啊啊!好的!好的 !给我1分钟!我添加另一个答案!
    • 如果是,你可以使用我的答案,如果不是,其他元素参考是什么来比较???
    • 是的初学者是级别的名称。假设我有两个导师。一位教授初级水平的射箭,一位教授初级水平的网球以及射箭和高级水平。您的查询将使我得到我只想要第一个的两个讲师。它也不能解决价格问题
    • 我认为你没有理解。我不想比较价格,我想用价格注释查询集。你的查询集也错了,应该是Instructor.objects.filter(city=city).filter(activityoffered__activity = activity, activityoffered__level = level)
    猜你喜欢
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    • 2013-10-30
    • 2017-11-17
    • 2016-06-30
    相关资源
    最近更新 更多