Django Interview-Fragen: ORM, Middleware und DRF im Detail
Django Interview-Fragen zu ORM-Optimierung mit FETCH_PEERS, Middleware-Architektur und DRF-Serializer-Performance. Codebeispiele mit Django 6.1.

Django-Vorstellungsgespräche konzentrieren sich auf drei zentrale Bereiche, die erfahrene Entwickler von Einsteigern unterscheiden: ORM-Beherrschung, Middleware-Architektur und Django REST Framework (DRF) Designmuster. Dieser Leitfaden analysiert die konkreten Fragen, die technische Interviewer im Jahr 2026 stellen, mit produktionsreifen Codebeispielen für Django 6.1 und DRF 3.18.
Django-Interviews behandeln selten grundlegende CRUD-Operationen. Der Fokus liegt auf QuerySet-Optimierung (select_related vs prefetch_related, der neue FETCH_PEERS-Modus), benutzerdefiniertem Middleware-Design und DRF-Serializer-Performance. Kandidaten, die N+1-Queries erklären und effiziente ViewSets schreiben können, übertreffen konstant jene, die nur generische Views kennen.
Django ORM Interview-Fragen: QuerySet-Optimierung
Die häufigste Django ORM Interview-Frage zielt auf das N+1-Problem ab. Bei einem Modell mit Fremdschlüsselbeziehungen müssen Kandidaten demonstrieren, wann select_related gegenüber prefetch_related zu verwenden ist.
# models.py
from django.db import models
class Company(models.Model):
name = models.CharField(max_length=200)
founded_year = models.IntegerField()
class Developer(models.Model):
name = models.CharField(max_length=200)
company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name="developers")
skills = models.ManyToManyField("Skill", related_name="developers")
class Skill(models.Model):
name = models.CharField(max_length=100)
category = models.CharField(max_length=50)Die Unterscheidung zwischen select_related und prefetch_related basiert auf der Art der Beziehung.
# queries.py — Correct approach for ForeignKey (single object)
developers = Developer.objects.select_related("company").all()
# Generates ONE SQL query with JOIN
# SELECT developer.*, company.* FROM developer INNER JOIN company ...
# Correct approach for ManyToMany (multiple objects)
developers = Developer.objects.prefetch_related("skills").all()
# Generates TWO SQL queries:
# 1. SELECT * FROM developer
# 2. SELECT * FROM skill INNER JOIN developer_skills WHERE developer_id IN (...)select_related führt einen SQL-JOIN durch und funktioniert mit ForeignKey und OneToOneField. prefetch_related führt eine separate Abfrage aus und funktioniert mit ManyToManyField und reverse ForeignKey-Beziehungen. Die Verwechslung führt entweder zu unnötigen JOINs bei großen Datensätzen oder zum gefürchteten N+1-Muster.
Django 6.1: FETCH_PEERS-Modus zur automatischen N+1-Vermeidung
Django 6.1 führt ein neues Fetch-Modus-System ein, das N+1-Abfragen auf ORM-Ebene behandelt. Beim Iterieren über ein QuerySet und Zugriff auf ein verknüpftes Feld lädt FETCH_PEERS dieses Feld für alle Instanzen im QuerySet mit einer einzigen zusätzlichen Abfrage.
# views.py — Django 6.1 FETCH_PEERS mode
from django.db import models
from .models import Book
# Traditional approach: requires explicit prefetch_related
books = Book.objects.prefetch_related("author").all()
# Django 6.1 approach: automatic peer fetching
books = Book.objects.fetch_mode(models.FETCH_PEERS)
for book in books:
print(book.author.name) # Only 2 queries total: books + all authorsDrei Fetch-Modi stehen zur Verfügung:
FETCH_ONE(Standard): Lädt das fehlende Feld nur für die aktuelle InstanzFETCH_PEERS: Lädt das Feld für alle Instanzen aus demselben QuerySetFETCH_RAISE: WirftFieldFetchBlockedfür performancekritischen Code, bei dem Lazy Loading verhindert werden muss
Für Interview-Zwecke sollten Kandidaten beide Ansätze kennen: explizites select_related/prefetch_related für detaillierte Kontrolle und FETCH_PEERS für automatische Optimierung beim Iterieren über QuerySets.
Fortgeschrittenes ORM: Custom Managers und QuerySet-Verkettung
Interviewer fragen häufig nach der Implementierung eines Custom Managers, der Geschäftslogik kapselt. Ziel ist es zu überprüfen, ob der Kandidat Djangos Manager-Muster versteht und wiederverwendbare Query-Interfaces schreiben kann.
# managers.py
from django.db import models
from django.utils import timezone
class ActiveDeveloperQuerySet(models.QuerySet):
def active(self):
"""Filter developers who logged in within the last 30 days."""
cutoff = timezone.now() - timezone.timedelta(days=30)
return self.filter(last_login__gte=cutoff)
def senior(self):
"""Filter developers with 5+ years of experience."""
return self.filter(years_experience__gte=5)
def by_skill(self, skill_name):
"""Filter developers by a specific skill."""
return self.filter(skills__name=skill_name)
class ActiveDeveloperManager(models.Manager):
def get_queryset(self):
return ActiveDeveloperQuerySet(self.model, using=self._db)
def active(self):
return self.get_queryset().active()Die wichtige Folgefrage lautet: "Warum ein Custom QuerySet statt nur einen Manager verwenden?" Die Antwort ist Verkettung. Custom QuerySet-Methoden können miteinander verkettet werden, während Manager-Methoden nach dem ersten Aufruf nicht verkettet werden können.
# usage.py — QuerySet chaining in action
# This works because each method returns a QuerySet
senior_python_devs = (
Developer.active_objects # custom manager
.active() # ActiveDeveloperQuerySet method
.senior() # chains another QuerySet method
.by_skill("Python") # chains a third method
.select_related("company") # standard QuerySet method still works
)Django 6.0 führte CompositePrimaryKey für Modelle ein, die mehrspaltige Primärschlüssel benötigen, plus ein integriertes Background-Tasks-Framework. Interview-Fragen zu diesen Features werden häufiger, insbesondere für Kandidaten, die mit Legacy-Datenbanken oder asynchronen Verarbeitungsanforderungen arbeiten.
Django Middleware Interview-Fragen: Request-Response-Pipeline
Middleware-Fragen testen das Verständnis eines Kandidaten für Djangos Request-Response-Lebenszyklus. Die Standardfrage: "Erklären Sie die Reihenfolge, in der Middleware eine Anfrage und eine Antwort verarbeitet."
Die Antwort folgt einem strikten Muster. Während einer Anfrage werden Middleware-Klassen von oben nach unten ausgeführt, wie in MIDDLEWARE definiert. Während einer Antwort werden sie von unten nach oben ausgeführt. Diese Zwiebelschicht-Architektur bedeutet, dass die erste Middleware in der Liste alles umschließt.
# middleware.py
import time
import logging
from django.http import JsonResponse
logger = logging.getLogger(__name__)
class RequestTimingMiddleware:
"""Logs the time taken to process each request."""
def __init__(self, get_response):
self.get_response = get_response # next middleware or view
def __call__(self, request):
start_time = time.monotonic()
response = self.get_response(request) # passes to next layer
duration_ms = (time.monotonic() - start_time) * 1000
logger.info(
"method=%s path=%s status=%d duration=%.2fms",
request.method,
request.path,
response.status_code,
duration_ms,
)
return responseEine häufige Folgefrage: "Wie würden Sie die Middleware-Kette kurzschließen?" Das Zurückgeben einer HttpResponse aus __call__ vor dem Aufruf von self.get_response(request) stoppt die Kette vollständig. Die restliche Middleware und die View werden nie ausgeführt.
# middleware.py — Rate limiting with short-circuit
from django.core.cache import cache
class RateLimitMiddleware:
"""Blocks requests exceeding 100 per minute per IP."""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
ip = request.META.get("REMOTE_ADDR")
cache_key = f"rate_limit:{ip}"
request_count = cache.get(cache_key, 0)
if request_count >= 100:
return JsonResponse( # short-circuits — view never executes
{"error": "Rate limit exceeded. Try again in 60 seconds."},
status=429,
)
cache.set(cache_key, request_count + 1, timeout=60)
return self.get_response(request)Middleware-Hooks: process_view, process_exception und process_template_response
Neben __call__ unterstützt Django-Middleware drei optionale Hook-Methoden. Interviewer verwenden diese, um die Tiefe des Wissens zu bewerten.
# middleware.py — Full middleware with all hooks
class AuditMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
return self.get_response(request)
def process_view(self, request, view_func, view_args, view_kwargs):
"""Called after URL resolution, before the view executes."""
logger.info("Calling view: %s", view_func.__name__)
return None # returning None continues normal processing
def process_exception(self, request, exception):
"""Called only if the view raises an exception."""
logger.error("View exception: %s", exception, exc_info=True)
return None # returning None lets Django's default handling proceed
def process_template_response(self, request, response):
"""Called if the response has a render() method (TemplateResponse)."""
response.context_data["audit_timestamp"] = time.time()
return response # must return a response with render()process_view wird nach der URL-Auflösung, aber vor der View ausgeführt. Die Rückgabe von None setzt die Ausführung fort; die Rückgabe einer HttpResponse führt zum Kurzschluss. process_exception wird nur bei unbehandelten Ausnahmen ausgelöst. process_template_response wird nur für TemplateResponse-Objekte ausgelöst, nicht für reguläre HttpResponse.
Bereit für deine Django-Interviews?
Übe mit unseren interaktiven Simulatoren, Flashcards und technischen Tests.
DRF Interview-Fragen: Serializer-Performance
Bei Fragen zu Django REST Framework-Serializern liegt der Fokus auf verschachtelter Serialisierung und den Performance-Auswirkungen verschiedener Ansätze. Die am häufigsten gestellte Frage: "Wie behandeln Sie verschachtelte Beziehungen, ohne N+1-Abfragen zu verursachen?"
# serializers.py
from rest_framework import serializers
from .models import Developer, Company, Skill
class SkillSerializer(serializers.ModelSerializer):
class Meta:
model = Skill
fields = ["name", "category"]
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model = Company
fields = ["name", "founded_year"]
class DeveloperSerializer(serializers.ModelSerializer):
company = CompanySerializer(read_only=True) # nested FK
skills = SkillSerializer(many=True, read_only=True) # nested M2M
class Meta:
model = Developer
fields = ["id", "name", "company", "skills"]Der Serializer allein löst das Performance-Problem nicht. Das ViewSet muss das QuerySet optimieren.
# views.py
from rest_framework import viewsets
from .models import Developer
from .serializers import DeveloperSerializer
class DeveloperViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = DeveloperSerializer
def get_queryset(self):
return (
Developer.objects
.select_related("company") # JOIN for FK
.prefetch_related("skills") # separate query for M2M
.order_by("-id")
)Ohne select_related und prefetch_related im ViewSet löst jeder serialisierte Entwickler individuelle Abfragen für seine Firma und Fähigkeiten aus. Bei einer Liste von 50 Entwicklern bedeutet das 1 + 50 + 50 = 101 Abfragen statt 3.
DRF Benutzerdefinierte Berechtigungen und Authentifizierung
Eine häufige DRF-Interview-Frage: "Schreiben Sie eine benutzerdefinierte Berechtigung, die den Zugriff basierend auf der Rolle des Benutzers und dem Eigentümer des Objekts einschränkt."
# permissions.py
from rest_framework.permissions import BasePermission
class IsOwnerOrAdmin(BasePermission):
"""
Object-level permission:
- Admin users can access any object
- Regular users can only access objects they own
"""
message = "Access restricted to the object owner or admin users."
def has_object_permission(self, request, view, obj):
if request.user.is_staff:
return True
# Assumes the model has an 'owner' field pointing to User
return obj.owner == request.user# views.py — Applying custom permissions
from rest_framework import viewsets, permissions
from .permissions import IsOwnerOrAdmin
class ProjectViewSet(viewsets.ModelViewSet):
permission_classes = [permissions.IsAuthenticated, IsOwnerOrAdmin]
def get_queryset(self):
# Non-admin users only see their own projects
if self.request.user.is_staff:
return Project.objects.all()
return Project.objects.filter(owner=self.request.user)
def perform_create(self, serializer):
serializer.save(owner=self.request.user) # auto-assign ownerDie Nuance, nach der Interviewer suchen: has_permission wird bei jeder Anfrage ausgeführt (Listen-Ebene), während has_object_permission nur ausgeführt wird, wenn get_object() aufgerufen wird (Detail-Ebene). Das Vergessen, get_queryset für List-Views zu überschreiben, erzeugt eine Sicherheitslücke, bei der Benutzer Objekte sehen können, die ihnen nicht gehören.
Das alleinige Verlassen auf has_object_permission ohne QuerySet-Filterung lässt den List-Endpoint ungeschützt. Object-Level-Permissions sollten stets mit einem gefilterten get_queryset kombiniert werden, um Zugriffskontrolle sowohl auf List- als auch Detail-Views durchzusetzen.
DRF Throttling und Pagination-Muster
Throttling und Pagination sind Standard-Folgefragen. Interviewer möchten sehen, dass Kandidaten produktionsreife API-Konfiguration verstehen.
# settings.py — Production DRF configuration
REST_FRAMEWORK = {
"DEFAULT_THROTTLE_CLASSES": [
"rest_framework.throttling.AnonRateThrottle",
"rest_framework.throttling.UserRateThrottle",
],
"DEFAULT_THROTTLE_RATES": {
"anon": "20/minute", # unauthenticated users
"user": "200/minute", # authenticated users
},
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.CursorPagination",
"PAGE_SIZE": 25,
}# pagination.py — Custom cursor pagination for consistent ordering
from rest_framework.pagination import CursorPagination
class CreatedAtCursorPagination(CursorPagination):
page_size = 25
ordering = "-created_at" # must be a unique, sequential field
cursor_query_param = "cursor" # ?cursor=abc123Cursor-basierte Pagination übertrifft Offset-Pagination bei großen Datensätzen, da sie keine Gesamtzeilenzählung erfordert. Der Kompromiss: Clients können nicht zu beliebigen Seiten springen. Dies ist die erwartete Antwort, wenn Interviewer fragen: "Warum würden Sie Cursor-Pagination gegenüber Seitennummer-Pagination wählen?"
Quellen
- Django 6.1 Release Notes — FETCH_PEERS Fetch-Modus zur automatischen N+1-Vermeidung
- Django 6.0 Release Notes — CompositePrimaryKey und Background Tasks Framework
- Django REST Framework Dokumentation — Serializer und ViewSet-Muster
Wichtige Erkenntnisse für die Django-Interview-Vorbereitung
- ORM-Optimierung: Die Query-Methode muss zum Beziehungstyp passen.
select_relatedfür ForeignKey/OneToOne,prefetch_relatedfür ManyToMany und reverse FK. DerFETCH_PEERS-Modus von Django 6.1 bietet automatische N+1-Vermeidung beim Iterieren über QuerySets. - Custom QuerySets: Ermöglichen verkettbare, wiederverwendbare Geschäftslogik. Custom Manager-Methoden können nach dem ersten Aufruf nicht verkettet werden, aber QuerySet-Methoden können es.
- Middleware-Architektur: Die Anfrage fließt von oben nach unten, die Antwort von unten nach oben. Das Kurzschließen durch Rückgabe einer Antwort vor
get_response()ist ein grundlegendes Muster für Rate Limiting, Auth-Checks und Request-Validierung. - DRF-Serializer-Performance: Verschachtelte Serializer erfordern explizite QuerySet-Optimierung im ViewSet. Ohne
select_related/prefetch_relatedverursacht die Serialisierung N+1-Abfragen bei Skalierung. - DRF-Berechtigungen: Kombinieren Sie
has_object_permissionmit einem gefiltertenget_queryset, um Zugriffskontrolle sowohl auf List- als auch Detail-Endpoints durchzusetzen. Object-Level-Permissions allein lassen List-Views ungeschützt. - Throttling und Pagination: Cursor-Pagination skaliert besser als Offset bei großen Tabellen. Konfigurieren Sie Throttle-Raten separat für anonyme und authentifizierte Benutzer.
Üben Sie diese Muster mit Django ORM Interview-Fragen und Django Middleware-Fragen auf SharpSkill, um vor dem echten Interview Sicherheit aufzubauen.
Fang an zu üben!
Teste dein Wissen mit unseren Interview-Simulatoren und technischen Tests.
Findest du den Bug in Django?
Ein echter Codeausschnitt, ein versteckter Bug, ein Versuch pro Tag. Zum Ausprobieren ohne Konto.

Geschrieben von
Anthony Fillion-MailletGründer von SharpSkill
Seit über 10 Jahren Fullstack-Entwickler. Er leitet SharpSkill und verantwortet alles, was hier erscheint.
Aktualisiert am 13. September 2026
Tags
Teilen
Verwandte Artikel

Fortgeschrittene Django Middleware 2026: Eigene Middleware, Logging und Interviewfragen
Umfassender Leitfaden zur Django Middleware in 2026: Request-Response-Zyklus, benutzerdefinierte Middleware-Klassen, async-fähige Middleware, Logging-Integration und häufige technische Interviewfragen.

Django 5.2: Custom Middleware und Signal-Handling für technische Interviews
Django 5.2 Middleware und Signals meistern: Middleware-Pipeline, asynchrone Middleware, pre_save/post_save Signals und häufige Interview-Fragen praxisnah erklärt.

Django und Celery: Asynchrone Aufgabenverarbeitung und Interviewfragen 2026
Django und Celery für asynchrone Task-Verarbeitung: Integration, Task-Routing, Celery Beat, Monitoring und die wichtigsten Interviewfragen 2026.