Gruppierung von Datensätzen im Django ORM

03.06.2024
Technologien Django ORM SQL

Eine einfache Möglichkeit Hierarchien in eine Datenstruktur zu bringen ist selbst referenzierende Foreign Keys zu verwenden. In diesem Beispiel haben wir ein CRM System, in dem Firmen und ihre Dachverbände (ebenfalls Firmen) organisiert werden. Um die Zuordnung von einer Firma zu einer anderen Firma, ihrem Dachverband, abzubilden, wird ein Foreign Key auf die Firmentabelle gesetzt:

IDNamedachverband_id
1Challenger Inc7
2Just.Works7
3Oida Technologies11
4Fastsales
5Karma Tech11
6Middleground Consulting4
7Works Group
8Fastsales Tech4
9Slowcoocking Inc4
10Jazz.Works7
11Consulting LTD

Ziel ist eine Listendarstellung dieser Firmen, allerdings nach ihrem Dachverband Gruppiert. Zuerst wird der Dachverband aufgeführt (erkennbar daran, dass keine Dachverband ID vorliegt) und dann alle Firmen die zu diesem Dachverband gehören. Diese Liste soll nach dem Namen des Dachverbands sortiert sein.

SQL

Im ersten Schritt überlegen wir, wie das Problem in reinem SQL (Postgres) zu lösen wäre. Es handelt sich nicht um ein Filterproblem, da lediglich die Sortierung angepasst werden muss.

Hier bietet es sich an, in der Abfrage eine neue Spalte mittels Coalesce zu definieren, die den Namen des Dachverbands enthält, ODER den eigenen Namen (falls kein Dachverband vorliegt). Hierzu führen wir einen Join der Tabelle auf sich selbst aus:

select
    f.id as "ID",
    f.name as "Firma",
    dv.name as "Dachverband",
    coalesce(dv.name, f.name, Null) as "cid"
from firmentabelle as f
    left join firmentabelle as dv on f.dachverband_id = f.id
order by cid, f.name
;

Damit erhalten wir die gewünschte Tabelle:

IDNameDachverbandcid
1Challenger IncWorks GroupWorks Group
2Just.WorksWorks GroupWorks Group
3Oida TechnologiesChallenger IncConsulting LTD
4FastsalesFastsales
5Karma TechConsulting LTDConsulting LTD
6Middleground ConsultingFastsalesFastsales
7Works GroupWorks Group
8Fastsales TechFastsalesFastsales
9Slowcoocking IncFastsalesFastsales
10Jazz.WorksWorks GroupWorks Group
11Consulting LTDConsulting LTD

Nach der Sortierung nach CID, Dachverband und Name ergibt sich folgendes Bild:

IDNameDachverbandcid
4FastsalesFastsales
9Slowcoocking IncFastsalesFastsales
6Middleground ConsultingFastsalesFastsales
8Fastsales TechFastsalesFastsales
7Works GroupWorks Group
1Challenger IncWorks GroupWorks Group
2Just.WorksWorks GroupWorks Group
10Jazz.WorksWorks GroupWorks Group
11Consulting LTDConsulting LTD
5Karma TechConsulting LTDConsulting LTD
3Oida TechnologiesConsulting LTDConsulting LTD

Django ORM

Erfreulicherweise stellt das Django ORM ebenfalls eine Coalesce-Funktionalität bereit. Hiermit kann ein Queryset annotiert werden, um dann nach dem Ergebnis zu sortieren. Die äquivalente Django ORM Query ist damit:

companies = Company.objects.all().annotate(
        cid=Coalesce("dachverband__name", "name")
    ).order_by("cid", "fach__name")

Damit ist diese Art der Gruppierung auch in Django möglich.

Impressum

Screenion GmbH

Büroanschrift:
Adenauerallee 21, 1. OG
61440 Oberursel

Rechnungsanschrift und Firmensitz:
Oberhöchstadter Straße 70a
61440 Oberursel
Deutschland

Fon: +49 (0)6171 9519800
Fax: 06171-9519808
post@screenion.de
Web: https://www.screenion.de

Geschäftsführer: Reto M. Kiefer
Amtsgericht: Bad Homburg HRB 13769
UmSt-Id gemäß §27a Umsatzsteuergesetz: DE273300425

Datenschutz

Mit Ihrem Zugriff auf unsere Website werden Daten, die eine Identifizierung ermöglichen könnten (z.B. IP-Adresse) und weitere Angaben wie Datum, Uhrzeit und aufgerufene Seite In Log-Files gespeichert.

Eine Auswertung der Daten, außer für statistische Zwecke sowie zur Optimierung unseres Internetangebots in anonymisierter Form, findet nicht statt. Sie können unsere Website grundsätzlich ohne Offenlegung Ihrer Identität nutzen.

Des Weiteren verwenden wir keine Cookies oder ähnliche Technologien. Sicher haben Sie schon den Hinweis vermisst :)


Wir verwenden Fotos von unsplash sowie pixabay und danken: