Seite 1 von 1

Django: Query mit Join, Summe und Filter auf DateField

Verfasst: Sonntag 11. Dezember 2011, 12:39
von sparrow
Hallo Forum,

ich bin gerade dabei eine kleine Anwendung auf Django umzustellen.
Ich muss ehrlich zugeben, dass ich das ORM-System, vor allem den Syntax, sehr gewöhnungsbedürftig finde. Obwohl ich schon eine Weile mit Django herum spiele werde ich damit irgendwie nicht warm.

Ich würde gerne folgende Query in Django abbilden:

Code: Alles auswählen

SELECT member.name, member.description, SUM(task.value) AS valuesum  
FROM contrib LEFT JOIN member ON (contrib.member = member.id) 
LEFT JOIN task ON (contrib.task = task.id) 
WHERE contrib.done >= "01.01.2011" 
GROUP BY member.name, member.description 
ORDER BY valuesum;
Die Definition der Modelle ist relativ simpel:

Code: Alles auswählen

class Member(models.Model):
    name = models.CharField(max_length = 50)
    description = models.TextField()
       
class Task(models.Model):
    name = models.CharField(max_length = 50)
    description = models.TextField()
    value = models.IntegerField()
                
class Contrib(models.Model):
    member = models.ForeignKey(Member)
    task = models.ForeignKey(Task)
    done = models.DateField()
Schon bei dem Versuch die Summe aller ausgeführten Tasks zu bekommen schlägt fehl:

Code: Alles auswählen

>>> from psystem.psys.models import Contrib
>>> from django.db.models import Sum
>>> test = Contrib.objects.all().aggregate(total=Sum('task.value'))
FieldError: Cannot resolve keyword 'task.value' into field. Choices are: done, id, member, task
Ja, ok, ich will aber nicht eines von den Feldern in der Tabelle aggregieren, sondern eines der Felder in den verbundenen Tabellen.

Kann mir da jemand auf die Sprünge helfen?

Gruß
Sparrow

Re: Django: Query mit Join, Summe und Filter auf DateField

Verfasst: Dienstag 13. Dezember 2011, 15:15
von sparrow
Hah, ich habs :)
Eigentlich war es schon fast wieder zu einfach. Tabellen die per Join verbunden sind kann man ansprechen, indem man Tabellenname und Feld mit einem doppelten Unterstrich trennt:

Code: Alles auswählen

test = Contrib.objects.all().aggregate(total=Sum('task__value'))