Agrégation Django: sommation de la Multiplication de deux champs

j'ai un modèle quelque chose comme ça

class Task(models.Model):
   progress = models.PositiveIntegerField()
   estimated_days = models.PositiveIntegerField()

Maintenant, je voudrais faire un calcul Sum(progress * estimated_days) au niveau de la base de données. En utilisant L'agrégation Django je peux avoir la somme pour chaque champ mais pas la somme de la multiplication des champs.

38
demandé sur Serjik 2012-08-28 22:54:51

4 réponses

mise à Jour: Django > = 1,8 veuillez suivre la réponse de @kmmbvnr

il est possible à l'aide de l'ORM de Django:

voici ce que vous devez faire:

from django.db.models import Sum

total = ( Task.objects
            .filter(your-filter-here)
            .aggregate(
                total=Sum('progress', field="progress*estimated_days")
             )['total']
         )

Note: si les deux champs sont de types différents, dites integer&float, le type de retour doit être passé comme premier paramètre de Sum

c'est une réponse tardive, mais je suppose que ça aidera quelqu'un qui cherche la même chose.

64
répondu sha256 2016-12-04 11:29:29
 from django.db.models import F

 Task.objects.aggregate(total=Sum(F('progress') * F('estimated_days')))['total']

constantes sont également disponibles, et tout est combinable:

 from django.db.models import Value

 Task.objects.aggregate(total=Sum('progress') / Value(10))['total']
54
répondu kmmbvnr 2016-08-10 09:27:16
  • django < 1.8

    from django.db.models import Sum
    MyModel.objects.filter(<filters>).aggregate(Sum('field1', field="field1*field2"))
    
  • django > = 1,8

    from django.db.models import Sum, F
    MyModel.objects.filter(<filters>).aggregate(Sum(F('field1')*F('field2')))
    
16
répondu Antstud 2016-10-13 01:45:10

vous avez plusieurs options:

  1. requête brute
  2. Emulbreh de sans-papiers approche
  3. Créer un troisième champ progress_X_estimated_days mettre à jour dans enregistrer écrasé méthode. Ensuite, faites l'agrégation à travers ce nouveau champ.

la réécriture:

class Task(models.Model):
   progress = models.PositiveIntegerField()
   estimated_days = models.PositiveIntegerField()
   progress_X_estimated_days = models.PositiveIntegerField(editable=False)

   def save(self, *args, **kwargs):
      progress_X_estimated_days = self.progress * self.estimated_days
      super(Task, self).save(*args, **kwargs)
2
répondu dani herrera 2017-05-23 11:54:50