Django аннотирует Multiple Sum с одним полем Many to Many и группировкой By
Относительно моего ранее заданного вопроса с таким же названием, давайте теперь возьмем эти модели:
class Server(models.Model):
name = models.CharField(max_length=100, null=False, blank=False)
cpu = models.PositiveIntegerField(null=False, blank=False)
ram = models.PositiveBigIntegerField(null=False, blank=False)
customer = models.ForeignKey(
Customer,
related_name='Servers',
on_delete=models.SET_NULL,
null=True,
blank=True
)
city = models.ForeignKey(
City,
related_name='Servers',
on_delete=models.CASCADE,
null=True,
blank=True
)
class Disk(models.Model):
server = models.ForeignKey(
Server,
related_name='Disks',
on_delete=models.CASCADE,
null=False,
blank=False
)
size = models.PositiveBigIntegerField(null=False, blank=False)
class Customer(models.Model):
name = models.CharField(max_length=255,
blank=True, null=True)
creation_date = models.DateTimeField(auto_now_add=True)
enabled = models.BooleanField(
blank=False, null=False, default=False)
class City(models.Model):
name = models.CharField(max_length=255,
blank=False, null=False)
country = models.ForeignKey(
Country,
related_name='Cities',
on_delete=models.CASCADE,
null=False,
blank=False
)
class Country(models.Model):
name = models.CharField(max_length=255,
blank=False, null=False)
Я хотел бы узнать, сколько серверов с суммой каждого CPU, RAM, дискового пространства я имею на одного клиента в одной стране.
- У каждого сервера есть город, каждый город находится в стране.
- У некоторых серверов еще нет клиентов, но мне все равно нужно знать, сколько серверов, CPU, ... у меня нет клиентов (в конечном итоге можно создать "Неизвестного" клиента, чтобы не устанавливать его на None в сервере).
Любая помощь будет признательна! Спасибо !!!
Я не уверен, что смогу помочь, так как думаю, что это слишком экспериментально, чтобы делать это без тестов.
Например, укажите страну и количество ваших серверов:
Server.objects.annotate(get_country=F("city__country")).values("get_country").annotate(count=Count('get_country'))
Теперь, если ваш результат выглядит как [{"countryA":150, "countryB": 17, ....}]. вы можете продолжить и заменить count на
Server.objects.annotate(get_country=F("city__country")).values("get_country").annotate(sum_cpu=Sum('cpu'), sum_ram=Sum('ram'), sum_disk=Sum('disk__size'))
Теперь, поскольку вы хотите, чтобы это было для каждого клиента, вам придется переформатировать его, чтобы начать с модели клиента вместо модели сервера.
Или, в зависимости от того, как вы показываете данные, ваш запрос может начинаться со слов
Server.objects.filter(customer=customer_obj).annotate....