Django. Как получить все поля в запросе ОБЪЕДИНЕНИЯ и СГРУППИРОВАТЬ ПО ним все

#python #sql #django #django-queryset

#python #sql #django #django-queryset

Вопрос:

Мне нужно объединить две таблицы, нащупать id и получить две функции агрегации по некоторым полям:

models.py

     class Products(models.Model):
        brand = models.CharField(max_length=45, blank=True, null=True)
        name = models.CharField(max_length=45, blank=True, null=True)
        cluster = models.CharField(max_length=45, blank=True, null=True)
        target_market = models.CharField(max_length=10, blank=True, null=True)
    
    class Vardata(models.Model):
        month = models.DateField(blank=True, null=True)
        sales_units = models.IntegerField(blank=True, null=True)
        price = models.FloatField(blank=True, null=True)
        fk_products = models.ForeignKey(MntProducts, models.DO_NOTHING, db_column='fk_products', blank=True, null=True)
  

Данные:

 Products.objects.all()
('vendor1', 'name1', 'it', 'C') #id-12
('vendor2', 'name2', 'it', 'B') #id-13
('vendor3', 'name3', 'bc', 'B') #id-14
  

….

 Vardata.objects.all()
('2020-03-01', '20', '180', '12')
('2020-04-01', '15', '182', '12')
('2020-05-01', '10', '178', '12')
('2020-03-01', '30', '120', '13')
('2020-04-01', '35', '122', '13')
('2020-05-01', '10', '118', '13')
('2020-03-01', '20', '150', '14')
('2020-04-01', '15', '155', '14')
('2020-05-01', '10', '156', '14')
  

мне нужен выход:

 exit[0]
{'id': 12, 
'brand': 'vendor1', 
'name': 'name1', 
'cluster': 'it', 
'target_market': 'C',
'sum__sales_units': 540,
'avg__price': 180
}
  

Я пытаюсь получить из INNER JOIN SQL-запроса базы данных со всеми полями из обеих таблиц до QuerySet ; и после, чтобы использовать annotate(Sum('sales_units', Avg('price')) для этого QuerySet :

Но мой запрос не принимает поля из родительской таблицы (Products) в запросе

views.py

 qry_total_execute = Vradata.objects.select_related("fk_products").filter(fk_products__in=list_products)
  
 >>> qry_total_execute.query('SELECT `vardata`.`id`, `vardata`.`month`, `vardata`.`sales_units`, vardata`.`price_rur`, `vardata`.`fk_products`, `products`.`id`, `products`.`brand`, `products`.`name`,  `products`.`cluster`, `products`.`target_market` FROM `vardata` INNER JOIN `products` ON (`vardata`.`fk_products` = `products`.`id`) WHERE `vardata`.`fk_products` IN (12, 13, 14)
  

он записывает
QuerySet с правильным количеством записей, но без полей products только из vardata (использование этого SQL-запроса в MySQL вручную дает правильный результат со всеми необходимыми полями.)

Задаваемые вопросы:

  1. Как получить все поля из базы данных booth?
  2. Как правильно использовать aggregate, если я получу правильный результат qry_total_execute ?
     qry_total_execute.values('id', 'brand', 'name', 'cluster', 'target_market').'annotate(Sum('sales_units', Avg('price'))
  

Правильно ли это?

Ответ №1:

Не используйте модель Vardata , позвольте использовать Products и помещать annotate напрямую

 qry_total_execute = Products.objects.filter(id__in=list_products).
        annotate(Sum(vardata__sales_units), Avg(vardata__price).
        values()