Django ORM - Get Max group by

时间:2017-07-31 10:04:32

标签: python django django-orm

我有三个型号。

数据中心

for (var control in this.Personal.controls) {
  this.Personal.controls[control].disable();
}

服务器

class Datacenter(models.Model):
    """
    Datacenter
    """

    uuid = models.UUIDField(verbose_name=_('UUID'), unique=True, default=uuid.uuid1, editable=False)
    name = models.CharField(_('name'), max_length=80, db_index=True)
    price_per_gigabyte = models.DecimalField(_('price per gigabyte'), max_digits=36, decimal_places=18, default=0, db_index=True)

    class Meta:
        verbose_name = _('datacenter')
        verbose_name_plural = _('datacenters')
        ordering = ['name']

    def __str__(self):
        return f'{self.name} / ${self.price_per_gigabyte:.2f} per GB'

存储

class Server(models.Model):
    """
    Server
    """

    uuid = models.UUIDField(verbose_name=_('UUID'), unique=True, default=uuid.uuid1, editable=False)
    hostname = models.CharField(_('hostname'), max_length=253, db_index=True)
    datacenter = models.ForeignKey(Datacenter, models.PROTECT, related_name="servers", related_query_name="server", verbose_name=_('datacenter'))
    useful_storage_capacity = models.PositiveSmallIntegerField(_('useful storage capacity'), default=0, db_index=True)

    class Meta:
        verbose_name = _('server')
        verbose_name_plural = _('servers')
        ordering = ['hostname']

    def __str__(self):
        return self.hostname

数据中心可以拥有多台服务器。从存储模型中我可以得到服务器上使用了多少空间。

我需要获得数据中心最大的免费空间服务器(只有一个)。

目前的情况如下:

class Storage(models.Model):
    """
    Storage Resource
    """

    uuid = models.UUIDField(verbose_name=_('UUID'), unique=True, default=uuid.uuid1, editable=False)
    server = models.ForeignKey(Server, models.PROTECT, related_name="storages", related_query_name="storage", verbose_name=_('server'))
    project = models.ForeignKey(Project, models.PROTECT, related_name="storages", related_query_name="storage", verbose_name=_('project'))
    space_used_latest_copy = models.PositiveSmallIntegerField(_('space used latest copy'), db_index=True)
    space_used_repository = models.PositiveSmallIntegerField(_('space used repository'), db_index=True)
    space_used_other = models.PositiveSmallIntegerField(_('space used other'), db_index=True)

    class Meta:
        verbose_name = _('storage resource')
        verbose_name_plural = _('storage resources')
        unique_together = (('server', 'project'),)
        ordering = ['server', 'project']

    def __str__(self):
        return f'{self.uuid} ({self.project}/{self.server})'

    def get_space_used_total(self):
        return self.space_used_latest_copy + self.space_used_repository + self.space_used_other

我注释了字段' free'其中包含服务器可用空间。我需要以某种方式通过数据中心对其进行分组,并获得最大的免费价值。所以最后我从每个数据中心获得一台也是最免费的服务器。

找不到任何示例如何以正确的方式执行此操作。什么是解决方案?

谢谢!

1 个答案:

答案 0 :(得分:1)

您需要使用values or values_list进行GROUP BY查询。

servers = Server.objects.all() \
            .values('datacenter__uuid', 'id') \
            .annotate(free=F('useful_storage_capacity') - Coalesce(Sum('storage__space_used_latest_copy'), V(0)) - Coalesce(Sum('storage__space_used_repository'), V(0))
                      - Coalesce(Sum('storage__space_used_other'), V(0))) \
            .annotate(max_free=Max(F('free'))
            .filter(free__gte=space_prepaid, free=F('max_free')) \
            .values('datacenter__uuid', 'id', 'free')
            .order_by('-free') 

我认为这应该为每个数据中心提供最多的免费服务器。 .values, .filter, and .annotate matter的排序所以这可能会有点棘手。尝试使用这些方法。