Moderne Web Apps Bouwen met Django

Door Lisa Peeters
Web Development

Django heeft zich bewezen als een van de meest krachtige en veelzijdige web frameworks voor Python. Van simple websites tot complexe enterprise applicaties, Django biedt de tools en structuur die nodig zijn om snel en veilig moderne webapplicaties te ontwikkelen.

Waarom Django?

Django volgt het principe "Don't Repeat Yourself" (DRY) en biedt een "batteries included" filosofie. Dit betekent dat veel functionaliteit die u nodig heeft voor webontwikkeling al ingebouwd is, waardoor u zich kunt concentreren op het bouwen van uw specifieke applicatielogica.

De Voordelen van Django

  • Rapid Development: Snel prototyping en development
  • Security First: Ingebouwde beveiliging tegen CSRF, SQL injection, XSS
  • Schaalbaarheid: Van MVP tot enterprise-level applicaties
  • Admin Interface: Automatisch gegenereerde admin panels
  • ORM: Krachtige database abstractie
  • Community: Uitgebreide ecosystem van packages

Django Project Structuur

Een goed georganiseerd Django project begint met de juiste structuur:

# Een nieuw Django project starten
django-admin startproject mijn_webapp
cd mijn_webapp
python manage.py startapp core

# Project structuur
mijn_webapp/
    manage.py
    mijn_webapp/
        __init__.py
        settings.py
        urls.py
        wsgi.py
    core/
        __init__.py
        models.py
        views.py
        urls.py
        admin.py

Models: Uw Data Structuur

Django's ORM maakt het eenvoudig om met databases te werken zonder SQL te schrijven:

# models.py
from django.db import models
from django.contrib.auth.models import User

class Product(models.Model):
    naam = models.CharField(max_length=200)
    beschrijving = models.TextField()
    prijs = models.DecimalField(max_digits=10, decimal_places=2)
    voorraad = models.IntegerField()
    gemaakt_op = models.DateTimeField(auto_now_add=True)
    
    def __str__(self):
        return self.naam

class Bestelling(models.Model):
    klant = models.ForeignKey(User, on_delete=models.CASCADE)
    producten = models.ManyToManyField(Product, through='BestellingItem')
    totaal = models.DecimalField(max_digits=10, decimal_places=2)
    besteld_op = models.DateTimeField(auto_now_add=True)

Views: De Bedrijfslogica

Views verwerken HTTP requests en retourneren responses:

# views.py
from django.shortcuts import render, get_object_or_404
from django.http import JsonResponse
from django.views.generic import ListView
from .models import Product

# Function-based view
def product_detail(request, product_id):
    product = get_object_or_404(Product, id=product_id)
    context = {'product': product}
    return render(request, 'products/detail.html', context)

# Class-based view
class ProductListView(ListView):
    model = Product
    template_name = 'products/list.html'
    context_object_name = 'producten'
    paginate_by = 20

# API view
def product_api(request, product_id):
    product = get_object_or_404(Product, id=product_id)
    data = {
        'naam': product.naam,
        'prijs': float(product.prijs),
        'voorraad': product.voorraad
    }
    return JsonResponse(data)

Templates: De Frontend

Django's template engine maakt het eenvoudig om dynamische HTML te genereren:

<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="nl">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}Mijn WebApp{% endblock %}</title>
    {% load static %}
    <link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
    <nav>
        <a href="{% url 'home' %}">Home</a>
        <a href="{% url 'products:list' %}">Producten</a>
    </nav>
    
    <main>
        {% block content %}{% endblock %}
    </main>
</body>
</html>

URL Routing

Django's URL systeem verbindt URLs met views:

# urls.py (main project)
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('core.urls')),
    path('products/', include('products.urls', namespace='products')),
]

# products/urls.py
from django.urls import path
from . import views

app_name = 'products'
urlpatterns = [
    path('', views.ProductListView.as_view(), name='list'),
    path('<int:product_id>/', views.product_detail, name='detail'),
    path('api/<int:product_id>/', views.product_api, name='api'),
]

Forms en Validation

Django's form systeem handelt validatie en rendering af:

# forms.py
from django import forms
from .models import Product

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = ['naam', 'beschrijving', 'prijs', 'voorraad']
        widgets = {
            'beschrijving': forms.Textarea(attrs={'rows': 4}),
            'prijs': forms.NumberInput(attrs={'step': '0.01'}),
        }
    
    def clean_prijs(self):
        prijs = self.cleaned_data['prijs']
        if prijs <= 0:
            raise forms.ValidationError("Prijs moet positief zijn")
        return prijs

Database Migraties

Django's migratiesysteem beheert database wijzigingen:

# Database migraties maken en toepassen
python manage.py makemigrations
python manage.py migrate

# Custom migratiebestanden voor complexe wijzigingen
python manage.py makemigrations --empty products

Security Best Practices

Veiligheid Tips

  • Gebruik altijd CSRF tokens in forms
  • Valideer alle user input op server-side
  • Gebruik Django's permission system
  • Configureer HTTPS voor productie
  • Update Django regelmatig voor security patches
  • Gebruik environment variables voor secrets

Performance Optimalisatie

Voor schaalbare applicaties zijn er verschillende optimalisatie technieken:

Database Optimalisatie

# Query optimalisatie
# Slecht: N+1 query probleem
for product in Product.objects.all():
    print(product.categorie.naam)

# Beter: select_related voor ForeignKey
for product in Product.objects.select_related('categorie'):
    print(product.categorie.naam)

# prefetch_related voor ManyToMany
products = Product.objects.prefetch_related('tags').all()

Caching Strategieën

# Template fragment caching
{% load cache %}
{% cache 500 product_list %}
    <!-- Expensive template code -->
{% endcache %}

# View-level caching
from django.views.decorators.cache import cache_page

@cache_page(60 * 15)  # Cache voor 15 minuten
def product_list(request):
    return render(request, 'products/list.html')

Testing uw Django App

Testing is cruciaal voor betrouwbare applicaties:

# tests.py
from django.test import TestCase, Client
from django.contrib.auth.models import User
from .models import Product

class ProductTests(TestCase):
    def setUp(self):
        self.product = Product.objects.create(
            naam="Test Product",
            prijs=19.99,
            voorraad=10
        )
    
    def test_product_str(self):
        self.assertEqual(str(self.product), "Test Product")
    
    def test_product_detail_view(self):
        response = self.client.get(f'/products/{self.product.id}/')
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "Test Product")

Deployment Overwegingen

Voor productie deployment zijn er verschillende aspecten om rekening mee te houden:

  • Static Files: Gebruik een CDN of web server voor static files
  • Database: PostgreSQL voor productie in plaats van SQLite
  • Environment Variables: Voor configuratie en secrets
  • Logging: Proper logging configuratie
  • Monitoring: Application performance monitoring

Django Ecosystem

De Django community heeft een rijke ecosystem van third-party packages:

  • Django REST Framework: Voor API development
  • Celery: Voor asynchrone taken
  • Django-allauth: Voor authentication
  • Django-debug-toolbar: Voor development debugging
  • Django-crispy-forms: Voor mooie form rendering

Klaar om Django te Leren?

Onze Web Development cursus leert u Django van beginner tot gevorderd niveau, met praktische projecten en moderne development practices.

Start Nu