Django Python

Django ORM: values und values_list

In Django erlaubt das ORM (Object-Relational Mapping) die Arbeit mit Datenbanken auf eine Python-typische Weise, ohne direkt SQL schreiben zu müssen. Zwei der nützlichsten Methoden für das Abrufen von Daten in einer bestimmten Struktur sind values() und values_list(). Diese Methoden helfen dabei, gezielt bestimmte Felder aus einer Datenbankabfrage abzurufen und das Abfrageergebnis in Form eines Dictionaries oder einer Liste darzustellen.

Django ORM: values und values_list

Was lerne ich in diesem Kurs?

Dieses Tutorial erklärt die Grundlagen der Methoden values und values_list und zeigt, wie sie in Django angewendet werden.

Einrichtung des Beispiels

Verwende ein einfaches Django-Modell als Grundlage für die Beispiele. Das Modell Book repräsentiert hier ein Buch mit den Feldern Titel, Autor und Veröffentlichungsjahr.

# models.py
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=100)
    year_published = models.IntegerField()

    def __str__(self):
        return self.title

Mit diesem Modell in Deiner Django-App können wir die values- und values_list-Methoden verwenden, um auf spezifische Daten zuzugreifen.

values(): Ergebnisse als Dictionary

Die Methode values() gibt die Felder als Dictionary-ähnliche Objekte zurück. Das ist nützlich, wenn Du bestimmte Felder und deren Namen als Schlüssel-Wert-Paare abrufen möchtest.

Alle Felder mit values()

# Alle Bücher und deren Felder als Dictionary abrufen
books = Book.objects.values()
for book in books:
    print(book)

Beispielausgabe:

{'id': 1, 'title': 'Django for Beginners', 'author': 'William S. Vincent', 'year_published': 2018}
{'id': 2, 'title': 'Two Scoops of Django', 'author': 'Daniel Roy Greenfeld', 'year_published': 2019}

Hier werden alle Felder des Modells Book als Dictionaries abgerufen. Jedes book-Dictionary enthält die Feldnamen und ihre entsprechenden Werte.

Bestimmte Felder mit values()

Du kannst auch nur bestimmte Felder abrufen, indem Du sie als Argumente an values() übergibst. Dies reduziert den Overhead, wenn nur bestimmte Daten benötigt werden.

# Nur Titel und Autor abrufen
books = Book.objects.values('title', 'author')
for book in books:
    print(book)

Beispielausgabe:

{'title': 'Django for Beginners', 'author': 'William S. Vincent'}
{'title': 'Two Scoops of Django', 'author': 'Daniel Roy Greenfeld'}

In diesem Fall gibt jedes book-Dictionary nur die Felder title und author zurück.

values_list(): Ergebnisse als Liste oder Tupel

Die Methode values_list() ist ähnlich wie values(), gibt jedoch die Daten als Liste oder Tupel zurück, anstatt als Dictionary. Dies kann nützlich sein, wenn Feldnamen nicht benötigt werden und die Daten in einer einfachen Struktur angeordnet werden sollen.

Alle Felder mit values_list()

# Alle Felder als Liste abrufen
books = Book.objects.values_list()
for book in books:
    print(book)

Beispielausgabe:

(1, 'Django for Beginners', 'William S. Vincent', 2018)
(2, 'Two Scoops of Django', 'Daniel Roy Greenfeld', 2019)

Hier gibt jedes book-Element ein Tupel zurück, das alle Felder des Modells Book enthält, jedoch ohne Feldnamen.

Bestimmte Felder mit values_list()

Genau wie bei values() kannst Du bei values_list() auch bestimmte Felder auswählen.

# Nur Titel und Jahr als Tupel abrufen
books = Book.objects.values_list('title', 'year_published')
for book in books:
    print(book)

Beispielausgabe:

('Django for Beginners', 2018)
('Two Scoops of Django', 2019)

Hier werden nur title und year_published als Tupel zurückgegeben.

flat=True: Eine einfache Liste für ein einzelnes Feld

Wenn nur ein einzelnes Feld mit values_list() abgerufen wird, kannst Du flat=True hinzufügen, um die Ergebnisse als einfache Liste anstatt als Liste von Tupeln zu erhalten.

# Nur die Titel als Liste abrufen
titles = Book.objects.values_list('title', flat=True)
print(titles)

Beispielausgabe:

['Django for Beginners', 'Two Scoops of Django']

Die Verwendung von flat=True vereinfacht die Struktur, wenn nur ein einzelnes Feld benötigt wird.

Praktische Anwendung von values() und values_list()

Aggregation von Daten

Die values()-Methode kann nützlich sein, wenn Du gruppierte Abfragen und Aggregationen durchführen möchtest. Angenommen, Du möchtest die Anzahl der Bücher pro Autor ermitteln.

from django.db.models import Count

# Anzahl der Bücher pro Autor
author_counts = Book.objects.values('author').annotate(book_count=Count('id'))
for entry in author_counts:
    print(entry)

Beispielausgabe:

{'author': 'William S. Vincent', 'book_count': 1}
{'author': 'Daniel Roy Greenfeld', 'book_count': 1}

Hier wird die Anzahl der Bücher für jeden Autor gezählt und als Dictionary zurückgegeben.

Optimierung der Abfragen

Die Verwendung von values() und values_list() kann die Performance optimieren, da nur die benötigten Felder abgerufen werden. Das spart Speicherplatz und Zeit, insbesondere bei großen Datenmengen.

# Nur IDs von Büchern abrufen
book_ids = Book.objects.values_list('id', flat=True)
print(book_ids)

Beispielausgabe:

[1, 2, 3, 4, 5]

Diese Abfrage gibt nur die IDs zurück, was effizienter ist, als das vollständige Abrufen aller Felder der Book-Objekte.