# Views (Kurzübersicht) Es gibt in Django zwei Haupttypen von Views, **Function-Based Views** und **Class-Based-Views**. ***Hinweis:*** Einige der folgenden Views existieren nur im Django REST Framework (DRF) und dienen der API-Entwicklung; die klassischen Django-Views funktionieren auch ohne DRF. # 1. **Function-Based Views (FBVs)** - Definiert als einfache Python-Funktionen. - Reagieren direkt auf HTTP-Anfragen (`request`). - Ideal für **einfache und schnelle Implementierungen**. **Beispiel (Django):** ```python def my_view(request): return HttpResponse("Hello, world!") ``` Im Kontext von **Django REST Framework (DRF)** kann der `@api_view`-Dekorator verwendet werden, um eine Funktion als API-View zu kennzeichnen: **Beispiel (DRF-only):** ```python from rest_framework.decorators import api_view from rest_framework.response import Response @api_view(['GET']) def my_api_view(request): return Response({"message": "Hello, API World!"}) ``` - Der `@api_view`-Dekorator ermöglicht es, dass meine Funktion als API-Endpoint fungiert, der JSON-Antworten zurückgibt und die richtigen HTTP-Methoden verarbeitet. # 2. **Class-Based Views (CBVs)** - Basieren auf Python-Klassen und erben meist von `View` oder anderen Django-View-Klassen. - Verwenden Methoden wie `get()`, `post()`, etc., um unterschiedliche HTTP-Methoden zu behandeln. - Gut geeignet für **strukturierte, wiederverwendbare und erweiterbare** Views. **Beispiel (Django):** ```python from django.views import View from django.http import HttpResponse class MyView(View): def get(self, request): return HttpResponse("Hello, world!") ``` **Beispiel (DRF-only):** ```python from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status class MyAPIView(APIView): def get(self, request, format=None): return Response({"message": "Hello, DRF world!"}, status=status.HTTP_200_OK) ``` ## Erweiterung von CBVs ### a) **Generic Class-Based Views (GCBVs)** - Vorgefertigte CBVs für häufige und große Aufgaben (CRUD). - Reduzieren Boilerplate-Code. **Beispiele (Django):** - `ListView`: Liste von Objekten anzeigen - `DetailView`: Einzelnes Objekt anzeigen - `CreateView`: Neues Objekt erstellen - `UpdateView`: Vorhandenes Objekt bearbeiten - `DeleteView`: Objekt löschen - `TemplateView`: Rendert hauptsächlich ein Template, oft ohne komplexe Logik - `RedirectView`: Leitet Benutzer automatisch zu einer anderen URL weiter **GenericAPIView – DRF-Basis:** - `GenericAPIView` ist die **Basisklasse** aller DRF-Generic-Views. - Erweitert `APIView` um zusätzliche, nützliche Funktionalitäten: - **Querysets:** `queryset`Attribut oder `get_queryset()`Methode - **Serializer:** `serializer_class`Attribut oder `get_serializer()` - **Pagination**, **Filtering**, **Ordering**, **Searching** - Wird selten direkt verwendet, sondern meist **in Kombination mit Mixins** oder durch die spezifischen Generics (z. B. `ListAPIView`). ```bash from rest_framework.generics import GenericAPIView from rest_framework.response import Response from .models import Employee from .serializers import EmployeeSerializer class EmployeeGenericView(GenericAPIView): queryset = Employee.objects.all() serializer_class = EmployeeSerializer def get(self, request, *args, **kwargs): instance = self.get_object() serializer = self.get_serializer(instance) return Response(serializer.data) ``` Auf der `GenericAPIView` basieren mehrere spezialisierte **Generic Views**, die jeweils typische CRUD-Operationen kapseln und oft in API-Projekten direkt verwendet werden. **Beispiele (DRF-only):** - `ListAPIView`: Liste von Objekten anzeigen (als JSON) - `DetailAPIView`: Einzelnes Objekt anzeigen (als JSON) - `CreateAPIView`: Neues Objekt erstellen (POST) - `UpdateAPIView`: Vorhandenes Objekt bearbeiten (PUT/PATCH) - `DestroyAPIView`: Objekt löschen (DELETE) - `RetrieveUpdateDestroyAPIView`: Einzelnes Objekt abrufen, bearbeiten und löschen (GET, PUT/PATCH, DELETE) - `ListCreateAPIView`: Liste von Objekten anzeigen (GET) und neues Objekt erstellen (POST) **Beispiel (DRF-only):** ```python from rest_framework.generics import ListAPIView from .models import Employee from .serializers import EmployeeSerializer class EmployeeListAPIView(ListAPIView): queryset = Employee.objects.all() serializer_class = EmployeeSerializer ``` ### b) **Mixins (DRF-only)** - **Wiederverwendbare Klassen**, die spezifische Funktionalität (z. B. Create, Update, Delete) einbringen. - Besonders nützlich in Kombination mit `GenericAPIView`. Generic Views übernehmen die “großen” Aufgaben, während Mixins die “kleinen” Aufgaben übernehmen. **Häufige Mixins (DRF-only):** - `ListModelMixin`: `GET` – Liste anzeigen - `CreateModelMixin`: `POST` – Objekt erstellen - `RetrieveModelMixin`: `GET` – Einzelnes Objekt holen - `UpdateModelMixin`: `PUT/PATCH` – Objekt aktualisieren - `DestroyModelMixin`: `DELETE` – Objekt löschen **Beispiel (DRF-only):** ```python from rest_framework import mixins, generics from .models import Employee from .serializers import EmployeeSerializer class EmployeeListCreateView(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = Employee.objects.all() serializer_class = EmployeeSerializer def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) ``` ### **c) Viewsets (DRF-only)** - Möchte ich nur Standard-CRUD-Operationen durchführen, kann ich auch einfach mit **Viewsets** arbeiten. Sie bündeln viele der Methoden von **Mixins** und **Generic Views** in einer einzigen Klasse. Das bedeutet, dass ich nicht jede Methode wie `list()`, `create()`, `retrieve()`, `update()` und `destroy()` manuell definieren muss – das übernimmt das Viewset automatisch. - Ein `Router` wie `SimpleRouter` oder `DefaultRouter` **generiert automatisch die URL-Routen** für alle Methoden, die mein `ViewSet` bereitstellt. Alternativ kann ich die URL-Routen auch manuell mit `.as_view()` zuweisen, wenn ich keinen Router nutzen möchte. - Das häufigst verwendete Viewset ist das `ModelViewSet` , welches automatisch alle wichtigen CRUD-Methoden inkl. einer **DetailView** zur Verfügung stellt: **Beispiel (DRF-only):** ```python from rest_framework import viewsets from .models import Employee from .serializers import EmployeeSerializer class EmployeeViewSet(viewsets.ModelViewSet): queryset = Employee.objects.all() serializer_class = EmployeeSerializer ``` - **Viewsets können auch mit Mixins kombiniert werden**, wenn ich gezielt nur bestimmte Methoden (z. B. nur `list` und `retrieve`) bereitstellen möchte. In diesem Fall verwende ich statt `ModelViewSet` gezielt einzelne Mixins in Kombination mit `GenericViewSet`. **Beispiel mit Mixins (DRF-only):** ```python from rest_framework import viewsets, mixins from .models import Employee from .serializers import EmployeeSerializer class EmployeeReadOnlyViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet): queryset = Employee.objects.all() serializer_class = EmployeeSerializer ```