Django: Query mit Join, Summe und Filter auf DateField

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

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
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

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'))
Antworten