2011-09-11 20 views
7

Estoy tratando de usar un método modelo en una consulta agregada django. No estoy seguro si es posible y puedo estar yendo de esta manera incorrecta.Uso de métodos modelo en los agregados

Aquí está el modelo que deseo consultar.

class ClassNumbers(models.Model): 
    """ 
    The class year level and number inline model for a booking 
    """ 
    booking = models.ForeignKey('Booking') 
    yearLevel = models.CharField(max_length=10, choices=YEAR_CHOICES, verbose_name='Year Level') 
    numberOfStudents = models.IntegerField(verbose_name='Number of Students') 

class Booking(models.Model): 
    # A shorter version of the model 
    date = models.DateField() 
    institution = models.ForeignKey(Institution) 

    def getStudentTotal(self): 
     # Total class numbers 
     classes = ClassNumbers.objects.filter(booking=self.id) 
     classTotal = 0 
     if (classes): 
      for c in classes: 
       classTotal += c.numberOfStudents 
     return classTotal 

    def getHDSV(self): 
     HDSVunits = { 
       'Full-Day': 2.0, 
       'Half-Day AM': 1.0, 
       'Half-Day PM': 1.0, 
       'Three-Quarter Day': 1.5, 
       '1 Hour': 0.5, 
       'Custom': 1.0, 
       } 
     numStudents = self.getStudentTotal() 
     result = numStudents * HDSVunits[self.price.name] 
     return result 

El método getHDSV devuelve una métrica de informes de uso interno, donde la vida de la aplicación. Deseo agregar la métrica en un total del mes entre un período de fechas.

No soy aggregate/annotate master. Mis intentos hasta ahora no han obtenido los resultados que busco.

Al final pregunté Bookings entre las fechas especificadas y luego hice un bucle sobre los resultados e ingresé la unidad de informes en un diccionario llamando al método getHDSV en cada iteración. Por supuesto, el diccionario resultante no está ordenado de la manera que me gustaría. Así que ahora estoy buscando ayuda.

Dada la forma en que se genera la métrica, ¿puedo llamar a un método modelo al agregar datos en una consulta? ¿O debería usar el diccionario HDSVunits al crear el aggregate? ¿O hay un mejor camino?

Gracias.

Respuesta

0

Si los datos que getHDSV está volviendo no es de la base de datos entonces aggregateannotate y no podrá ser utilizado para recopilar estadísticas sobre el mismo.

1

Tiene una configuración bastante difícil, puede ser más fácil tener la asignación de HDSVunits en el modelo Price para facilitar el acceso en las consultas.

Lo mejor que puedo llegar a decir algo como esto:

Booking.objects.aggregate(
    hdsv=(
     Sum('classnumbers__numberofstudents') * 
     Case(
      When(price__name='Full-Day', then=2.0), 
      When(price__name='Half-Day AM', then=1.0), 
      When(price__name='Full-Day PM', then=1.0), 
      When(price__name='Three-Quarter Day', then=1.5), 
      When(price__name='1 Hour', then=0.5), 
      When(price__name='Custom', then=1.0), 
      output_field=FloatField(), 
     ) 
    ) 
) 

Si el valor HDSV se almacena como un campo en el modelo Price, usted podría simplemente hacer:

Booking.objects.aggregate(
    hdsv=Sum('classnumbers__numberofstudents') * F('price__hdsv')) 

En una nota al margen, realmente debería considerar seguir el Python naming convensions que facilitaría a otros desarrolladores de Python ayudarlo.

Cuestiones relacionadas