0 Tage Serie
python / expert
Snippet

Django QuerySet Optimierung mit only() und defer() für Selektives Laden von Feldern

Djangos only() Methode gibt an welche Felder sofort geladen werden sollen, wobei alle anderen als deferred Fields verzögert geladen werden und bei Zugriff bei Bedarf abgerufen werden. Die defer() Methode gibt Felder an die von der initialen Query ausgeschlossen werden, nützlich für große Textfelder oder JSON-Felder die selten sofort benötigt werden. Das Kombinieren mit select_related() für Foreign Keys und Sortierung mit Slicing optimiert sowohl die Query-Struktur als auch die Ergebnisgröße. values_list() mit flat=True gibt einfache Python-Werte statt Model-Instanzen zurück für maximale Performance wenn Sie keine vollständigen Objekte benötigen.

snippet.py
python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
summary = models.TextField()
author = models.ForeignKey('Author', on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
metadata = models.JSONField(default=dict)
# Fetch only required fields - reduces memory and query time
titles_and_dates = Article.objects.only('title', 'created_at').filter(
author__name__icontains='python'
)
# Defer heavy fields that are rarely accessed immediately
articles_with_deferred_content = Article.objects.defer(
'content', 'metadata'
).select_related('author').all()
# Combine with ordering and slicing
recent_titles = Article.objects.only(
'title', 'created_at'
).order_by('-created_at')[:10]
# Chain with values() for dictionaries instead of model instances
author_names = Article.objects.values_list(
'author__name', flat=True
).distinct()[:5]
django
Erklärung
1
Article.objects.only('title', 'created_at')
only() lädt angegebene Felder sofort, verzögert alle anderen
2
Article.objects.defer('content', 'metadata')
defer() schließt angegebene Felder von initialer Query aus
3
.select_related('author')
select_related() führt SQL JOIN aus um verknüpften Author in gleicher Query zu laden
4
.order_by('-created_at')[:10]
Sortiert nach created_at absteigend und begrenzt auf 10 Ergebnisse
5
values_list('author__name', flat=True)
values_list() gibt Tupel zurück, flat=True gibt einfache Liste von Werten zurück
6
.distinct()[:5]
distinct() eliminiert Duplikate vor dem Slicing auf 5 Ergebnisse