Ontwikkel een REST API met Django REST Framework
description
Met deze prompt kan de gebruiker stapsgewijs een REST API ontwikkelen met Django REST Framework, waarbij specifieke behoeften en authenticatie worden meegenomen. Het biedt praktische richtlijnen en voorkomt veelvoorkomende fouten, wat resulteert in een robuuste en schaalbare API.
prompt
Help me bij het ontwerpen en implementeren van een REST API met Django REST Framework. Beschrijf mijn API-vereisten en endpoints: <beschrijf je API ...
try_prompt
generate_helper
disclaimerOnPageApi
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een overzicht van je API-vereisten en een stappenplan voor het ontwerpen en implementeren met Django REST Framework (DRF):
**API-Vereisten:**
1. **Gebruikersbeheer:**
- Registratie van nieuwe gebruikers
- Inloggen en verkrijgen van een authenticatietoken
2. **Productcatalogus:**
- Opvragen van een lijst van producten
- (Optioneel) Detailinformatie van een product
3. **Bestellingen:**
- Plaatsen van nieuwe bestellingen
- (Optioneel) Ophalen van bestaande bestellingen
**Endpoints:**
| Endpoint | Methode | Beschrijving | Authenticatie |
|-------------------------|---------|--------------------------------------------|----------------------------------|
| `/api/register/` | POST | Nieuwe gebruiker registreren | Geen |
| `/api/login/` | POST | Inloggen en token verkrijgen | Geen |
| `/api/products/` | GET | Lijst van producten ophalen | Vereist token |
| `/api/products/<id>/` | GET | Detailinformatie van een product | Vereist token |
| `/api/orders/` | POST | Nieuwe bestelling plaatsen | Vereist token |
| `/api/orders/<id>/` | GET | Bestelling details opvragen | Vereist token |
**Authenticatie:**
- Gebruik token-gebaseerde authenticatie met Django REST Framework's `TokenAuthentication`.
- Na registratie of login wordt een token gegenereerd dat je bij verdere verzoeken meestuurt via de header: `Authorization: Token <token>`.
---
**Stappenplan voor implementatie:**
1. **Project en app aanmaken:**
```bash
django-admin startproject mijnproject
cd mijnproject
python manage.py startapp api
```
2. **Installeer Django REST Framework en REST Framework Token auth:**
```bash
pip install djangorestframework
pip install djangorestframework.authtoken
```
3. **Voeg toe aan `settings.py`:**
```python
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework.authtoken',
'api',
]
```
4. **Configureer REST Framework in `settings.py`:**
```python
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
```
5. **Maak modellen aan voor Product en Bestelling in `models.py`:**
```python
from django.contrib.auth.models import User
from django.db import models
class Product(models.Model):
naam = models.CharField(max_length=100)
beschrijving = models.TextField()
prijs = models.DecimalField(max_digits=8, decimal_places=2)
def __str__(self):
return self.naam
class Bestelling(models.Model):
gebruiker = models.ForeignKey(User, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
hoeveelheid = models.IntegerField()
besteld_op = models.DateTimeField(auto_now_add=True)
```
6. **Maak serializers voor deze modellen (`serializers.py`):**
```python
from rest_framework import serializers
from .models import Product, Bestelling
from django.contrib.auth.models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['username', 'password']
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
user = User.objects.create_user(**validated_data)
return user
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
class BestellingSerializer(serializers.ModelSerializer):
class Meta:
model = Bestelling
fields = '__all__'
```
7. **Maak views voor de endpoints (`views.py`):**
```python
from rest_framework import generics, permissions, views
from rest_framework.response import Response
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from .models import Product, Bestelling
from .serializers import UserSerializer, ProductSerializer, BestellingSerializer
# Registratie
class RegisterView(generics.CreateAPIView):
serializer_class = UserSerializer
permission_classes = [permissions.AllowAny]
# Login om token te krijgen
class CustomAuthToken(ObtainAuthToken):
def post(self, request, *args, **kwargs):
response = super().post(request, *args, **kwargs)
token = Token.objects.get(user_id=response.data['user'])
return Response({'token': token.key})
# Producten lijst
class ProductList(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
permission_classes = [permissions.IsAuthenticated]
# Product detail
class ProductDetail(generics.RetrieveAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
permission_classes = [permissions.IsAuthenticated]
# Bestelling plaatsen
class BestellingCreate(generics.CreateAPIView):
serializer_class = BestellingSerializer
permission_classes = [permissions.IsAuthenticated]
def perform_create(self, serializer):
serializer.save(gebruiker=self.request.user)
```
8. **Configureer URLs (`urls.py`) in je app:**
```python
from django.urls import path
from .views import RegisterView, CustomAuthToken, ProductList, ProductDetail, BestellingCreate
urlpatterns = [
path('register/', RegisterView.as_view(), name='register'),
path('login/', CustomAuthToken.as_view(), name='login'),
path('products/', ProductList.as_view(), name='product-list'),
path('products/<int:pk>/', ProductDetail.as_view(), name='product-detail'),
path('orders/', BestellingCreate.as_view(), name='bestelling-create'),
]
```
9. **Configureer hoofd `urls.py` van het project:**
```python
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('api.urls')),
]
```
10. **Migraties uitvoeren en database migreren:**
```bash
python manage.py makemigrations
python manage.py migrate
```
11. **Server starten:**
```bash
python manage.py runserver
```
Nu heb je een werkende REST API met gebruikersregistratie, login met token, productcatalogus ophalen en bestellingen plaatsen, allemaal beveiligd met token-authenticatie.
provider: deepseek
model: deepseek-chat
Zeker, ik help je graag bij het ontwerpen en implementeren van je REST API met Django REST Framework. Hier is een complete handleiding in het Nederlands:
## API Vereisten & Endpoints Overzicht
### 1. Gebruikersbeheer
- **Registratie**: Nieuwe gebruikers aanmaken
- **Login**: Bestaande gebruikers authenticeren
- **Token-beheer**: Authenticatietokens genereren en vernieuwen
### 2. Productcatalogus
- **Producten ophalen**: Lijst van alle producten
- **Productdetails**: Specifiek product bekijken
- **Filteren & Zoeken**: Producten filteren op categorie/kenmerken
### 3. Bestellingen
- **Bestelling plaatsen**: Nieuwe bestelling aanmaken
- **Bestelgeschiedenis**: Bestaande bestellingen opvragen
- **Besteldetails**: Specifieke bestelling bekijken
## Implementatiestappen
### 1. Project Setup
```bash
pip install django djangorestframework djangorestframework-simplejwt
```
### 2. Models (models.py)
```python
from django.contrib.auth.models import AbstractUser
from django.db import models
class Gebruiker(AbstractUser):
telefoon = models.CharField(max_length=15, blank=True)
class Product(models.Model):
naam = models.CharField(max_length=100)
beschrijving = models.TextField()
prijs = models.DecimalField(max_digits=10, decimal_places=2)
voorraad = models.IntegerField(default=0)
actief = models.BooleanField(default=True)
class Bestelling(models.Model):
gebruiker = models.ForeignKey(Gebruiker, on_delete=models.CASCADE)
producten = models.ManyToManyField(Product, through='BestelRegel')
totaal_bedrag = models.DecimalField(max_digits=10, decimal_places=2)
datum = models.DateTimeField(auto_now_add=True)
status = models.CharField(max_length=20, default='in_afwachting')
class BestelRegel(models.Model):
bestelling = models.ForeignKey(Bestelling, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
hoeveelheid = models.IntegerField()
prijs = models.DecimalField(max_digits=10, decimal_places=2)
```
### 3. Serializers (serializers.py)
```python
from rest_framework import serializers
from .models import Gebruiker, Product, Bestelling, BestelRegel
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class GebruikerRegistratieSerializer(serializers.ModelSerializer):
wachtwoord = serializers.CharField(write_only=True)
class Meta:
model = Gebruiker
fields = ('id', 'username', 'email', 'wachtwoord', 'first_name', 'last_name')
def create(self, validated_data):
gebruiker = Gebruiker.objects.create_user(
username=validated_data['username'],
email=validated_data['email'],
password=validated_data['wachtwoord'],
first_name=validated_data.get('first_name', ''),
last_name=validated_data.get('last_name', '')
)
return gebruiker
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
class BestelRegelSerializer(serializers.ModelSerializer):
class Meta:
model = BestelRegel
fields = '__all__'
class BestellingSerializer(serializers.ModelSerializer):
regels = BestelRegelSerializer(many=True, read_only=True)
class Meta:
model = Bestelling
fields = '__all__'
class MijnTokenObtainPairSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super().get_token(user)
token['username'] = user.username
return token
```
### 4. Views (views.py)
```python
from rest_framework import generics, permissions, status
from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes
from rest_framework_simplejwt.views import TokenObtainPairView
from .models import Gebruiker, Product, Bestelling
from .serializers import (
GebruikerRegistratieSerializer, ProductSerializer,
BestellingSerializer, MijnTokenObtainPairSerializer
)
class GebruikerRegistratieView(generics.CreateAPIView):
queryset = Gebruiker.objects.all()
serializer_class = GebruikerRegistratieSerializer
permission_classes = [permissions.AllowAny]
class MijnTokenObtainPairView(TokenObtainPairView):
serializer_class = MijnTokenObtainPairSerializer
class ProductLijstView(generics.ListAPIView):
queryset = Product.objects.filter(actief=True)
serializer_class = ProductSerializer
permission_classes = [permissions.AllowAny]
class ProductDetailView(generics.RetrieveAPIView):
queryset = Product.objects.filter(actief=True)
serializer_class = ProductSerializer
permission_classes = [permissions.AllowAny]
class BestellingAanmakenView(generics.CreateAPIView):
serializer_class = BestellingSerializer
permission_classes = [permissions.IsAuthenticated]
def perform_create(self, serializer):
serializer.save(gebruiker=self.request.user)
class BestellingLijstView(generics.ListAPIView):
serializer_class = BestellingSerializer
permission_classes = [permissions.IsAuthenticated]
def get_queryset(self):
return Bestelling.objects.filter(gebruiker=self.request.user)
```
### 5. URLs (urls.py)
```python
from django.urls import path, include
from rest_framework_simplejwt.views import TokenRefreshView
from .views import (
GebruikerRegistratieView, MijnTokenObtainPairView,
ProductLijstView, ProductDetailView,
BestellingAanmakenView, BestellingLijstView
)
urlpatterns = [
# Authenticatie
path('registreer/', GebruikerRegistratieView.as_view(), name='registreer'),
path('token/', MijnTokenObtainPairView.as_view(), name='token_obtain_pair'),
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
# Producten
path('producten/', ProductLijstView.as_view(), name='producten_lijst'),
path('producten/<int:pk>/', ProductDetailView.as_view(), name='product_detail'),
# Bestellingen
path('bestellingen/', BestellingLijstView.as_view(), name='bestellingen_lijst'),
path('bestellingen/plaatsen/', BestellingAanmakenView.as_view(), name='bestelling_plaatsen'),
]
```
### 6. Settings (settings.py)
```python
INSTALLED_APPS = [
# ... bestaande apps
'rest_framework',
'rest_framework_simplejwt',
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
}
from datetime import timedelta
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
}
```
## API Endpoints Overzicht
| Endpoint | Methode | Beschrijving | Authenticatie |
|----------|---------|--------------|---------------|
| `/api/registreer/` | POST | Nieuwe gebruiker registreren | Geen |
| `/api/token/` | POST | JWT token verkrijgen | Geen |
| `/api/token/refresh/` | POST | Token vernieuwen | Geen |
| `/api/producten/` | GET | Alle producten ophalen | Geen |
| `/api/producten/<id>/` | GET | Specifiek product ophalen | Geen |
| `/api/bestellingen/` | GET | Eigen bestellingen ophalen | JWT Required |
| `/api/bestellingen/plaatsen/` | POST | Nieuwe bestelling plaatsen | JWT Required |
## Gebruiksvoorbeelden
### Registratie:
```bash
curl -X POST http://localhost:8000/api/registreer/ \
-H "Content-Type: application/json" \
-d '{"username": "jan", "email": "jan@voorbeeld.nl", "wachtwoord": "wachtwoord123"}'
```
### Login:
```bash
curl -X POST http://localhost:8000/api/token/ \
-H "Content-Type: application/json" \
-d '{"username": "jan", "password": "wachtwoord123"}'
```
### Producten ophalen:
```bash
curl http://localhost:8000/api/producten/
```
### Bestelling plaatsen (met token):
```bash
curl -X POST http://localhost:8000/api/bestellingen/plaatsen/ \
-H "Authorization: Bearer <jouw_token>" \
-H "Content-Type: application/json" \
-d '{"producten": [{"product": 1, "hoeveelheid": 2}]}'
```
Deze implementatie biedt een solide basis voor je REST API met token-gebaseerde authenticatie volgens je vereisten.