【问题标题】:Django model aggregationDjango 模型聚合
【发布时间】:2011-06-05 14:20:58
【问题描述】:

我有一个简单的分层模型,其中包含一个 Person 和 RunningScore 作为孩子。 该模型存储了许多用户的跑分数据,简化如下:

class Person(models.Model):
   firstName = models.CharField(max_length=200)
   lastName = models.CharField(max_length=200)  

class RunningScore(models.Model):
   person = models.ForeignKey('Person', related_name="scores")
   time = models.DecimalField(max_digits=6, decimal_places=2)   

如果我得到一个 Person ,它带有与之关联的所有 RunningScores,这是标准行为。我的问题很简单:如果我想得到一个只有 RunningScore 孩子的 Person (假设结果更好,也就是 min(time) )我该怎么办? 我阅读了官方 Django 文档,但没有找到 解决方案。

【问题讨论】:

    标签: django django-models django-aggregation


    【解决方案1】:

    我不能 100% 确定我是否明白你的意思,但也许这会有所帮助:

    from django.db.models import Min
    Person.objects.annotate(min_running_time=Min('time'))
    

    查询集将获取带有 min_running_time 附加属性的 Person 对象。

    您还可以添加过滤器:

    Person.objects.annotate(min_running_time=Min('time')).filter(firstName__startswith='foo')
    

    访问第一个对象的min_running_time 属性:

    first_person = Person.objects.annotate(min_running_score=Min('time'))[0]
    print first_person.min_running_time
    

    编辑:

    您可以定义如下方法或属性来获取相关对象:

    class Person(models.Model):
    ...
        @property
        def best_runner(self):
            try:
                return self.runningscore_set.order_by('time')[0]
            except IndexError:
                return None
    

    【讨论】:

    • 是的,如果我只需要最佳运行时间但我需要整个 Child 对象而不仅仅是“时间”字段,那么您的解决方案是正确的。
    • 您的解决方案是我正在寻找的。我做了一点修改:def best_runner(self):
    【解决方案2】:

    如果您只想为一个 Person 获得一个 RunningScore,您可以使用 odering 并将您的查询集限制为 1 个对象。 像这样的:

    Person.runningscore_set.order_by('-time')[0]
    

    这是关于限制查询集的文档:

    https://docs.djangoproject.com/en/1.3/topics/db/queries/#limiting-querysets

    【讨论】:

      猜你喜欢
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-11
      • 2016-07-23
      • 2010-12-01
      相关资源
      最近更新 更多