Web Development met Python

Web Development met Python

Python is niet alleen populair voor data science en automatisering, maar ook een uitstekende keuze voor web development. Met krachtige frameworks zoals Flask en Django kunt u robuuste, schaalbare web applicaties bouwen. In dit artikel verkennen we hoe u Python kunt gebruiken voor web development.

Waarom Python voor Web Development?

Python biedt verschillende voordelen voor web development:

  • Snelle ontwikkeling: Python's eenvoudige syntax versnelt het ontwikkelproces
  • Rijke ecosystem: Duizenden packages en bibliotheken beschikbaar
  • Schaalbaarheid: Gebruikt door grote bedrijven zoals Instagram, Spotify, en Dropbox
  • Beveiliging: Ingebouwde beveiligingsfuncties in frameworks
  • Community: Grote, actieve community met uitgebreide documentatie

Populaire Python Web Frameworks

Flask: Micro-framework voor Flexibiliteit

Flask is een lightweight micro-framework dat u volledige controle geeft over uw applicatie-architectuur.

Uw Eerste Flask Applicatie

from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)

# Basis route
@app.route('/')
def home():
    return render_template('index.html')

# Route met parameter
@app.route('/user/<name>')
def user_profile(name):
    return f'Welkom, {name}!'

# POST route voor formulieren
@app.route('/contact', methods=['GET', 'POST'])
def contact():
    if request.method == 'POST':
        name = request.form['name']
        email = request.form['email']
        message = request.form['message']
        
        # Verwerk formulier data
        # ... save to database ...
        
        return redirect(url_for('thank_you'))
    
    return render_template('contact.html')

@app.route('/thank-you')
def thank_you():
    return render_template('thanks.html')

if __name__ == '__main__':
    app.run(debug=True)

Flask met Database (SQLAlchemy)

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

# Model definitie
class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    content = db.Column(db.Text, nullable=False)
    date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    author = db.Column(db.String(20), nullable=False)

    def __repr__(self):
        return f"Post('{self.title}', '{self.date_posted}')"

# Routes
@app.route('/posts')
def posts():
    posts = Post.query.all()
    return render_template('posts.html', posts=posts)

@app.route('/post/<int:post_id>')
def post(post_id):
    post = Post.query.get_or_404(post_id)
    return render_template('post.html', post=post)

Django: Full-Featured Framework

Django is een high-level framework dat een "batteries included" benadering volgt, met veel functionaliteit out-of-the-box.

Django Project Structuur

# Django project starten
# django-admin startproject myproject
# cd myproject
# python manage.py startapp blog

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

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    date_posted = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

# views.py
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from .models import Post

def home(request):
    posts = Post.objects.all()
    return render(request, 'blog/home.html', {'posts': posts})

def post_detail(request, post_id):
    post = get_object_or_404(Post, id=post_id)
    return render(request, 'blog/post_detail.html', {'post': post})

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

urlpatterns = [
    path('', views.home, name='blog-home'),
    path('post/<int:post_id>/', views.post_detail, name='post-detail'),
]

RESTful API Development

Python is uitstekend geschikt voor het bouwen van RESTful APIs.

Flask-RESTful API

from flask import Flask, jsonify, request
from flask_restful import Api, Resource

app = Flask(__name__)
api = Api(app)

# In-memory database (normaal zou je een echte database gebruiken)
tasks = [
    {
        'id': 1,
        'title': 'Leer Python',
        'description': 'Volg een Python cursus',
        'done': False
    },
    {
        'id': 2,
        'title': 'Bouw een web app',
        'description': 'Maak een Flask applicatie',
        'done': False
    }
]

class TaskList(Resource):
    def get(self):
        return jsonify({'tasks': tasks})
    
    def post(self):
        data = request.get_json()
        task = {
            'id': len(tasks) + 1,
            'title': data['title'],
            'description': data.get('description', ''),
            'done': False
        }
        tasks.append(task)
        return jsonify({'task': task}), 201

class Task(Resource):
    def get(self, task_id):
        task = next((task for task in tasks if task['id'] == task_id), None)
        if task is None:
            return {'message': 'Task not found'}, 404
        return jsonify({'task': task})
    
    def put(self, task_id):
        task = next((task for task in tasks if task['id'] == task_id), None)
        if task is None:
            return {'message': 'Task not found'}, 404
        
        data = request.get_json()
        task.update(data)
        return jsonify({'task': task})
    
    def delete(self, task_id):
        global tasks
        tasks = [task for task in tasks if task['id'] != task_id]
        return {'message': 'Task deleted'}

api.add_resource(TaskList, '/api/tasks')
api.add_resource(Task, '/api/tasks/<int:task_id>')

Django REST Framework

# serializers.py
from rest_framework import serializers
from .models import Post

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ['id', 'title', 'content', 'date_posted', 'author']

# views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .serializers import PostSerializer

@api_view(['GET', 'POST'])
def post_list(request):
    if request.method == 'GET':
        posts = Post.objects.all()
        serializer = PostSerializer(posts, many=True)
        return Response(serializer.data)
    
    elif request.method == 'POST':
        serializer = PostSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET', 'PUT', 'DELETE'])
def post_detail(request, pk):
    try:
        post = Post.objects.get(pk=pk)
    except Post.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)
    
    if request.method == 'GET':
        serializer = PostSerializer(post)
        return Response(serializer.data)
    
    elif request.method == 'PUT':
        serializer = PostSerializer(post, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    elif request.method == 'DELETE':
        post.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

Authenticatie en Autorisatie

Beveiliging is cruciaal bij web development. Hier zijn enkele benaderingen:

Flask-Login voor Sessie Beheer

from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'

class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password_hash = db.Column(db.String(128))

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        
        user = User.query.filter_by(username=username).first()
        if user and check_password_hash(user.password_hash, password):
            login_user(user)
            return redirect(url_for('dashboard'))
        
        flash('Invalid username or password')
    
    return render_template('login.html')

@app.route('/dashboard')
@login_required
def dashboard():
    return render_template('dashboard.html')

Database Migraties

Database schema veranderingen beheren is essentieel voor productie applicaties.

Flask-Migrate

# Installatie: pip install Flask-Migrate
from flask_migrate import Migrate

migrate = Migrate(app, db)

# Commando's:
# flask db init        # Initialiseer migraties
# flask db migrate -m "Add user table"  # Maak migratie
# flask db upgrade     # Voer migraties uit

Testing Web Applicaties

Testen is cruciaal voor betrouwbare web applicaties.

Flask Testing

import unittest
from app import app, db

class BasicTestCase(unittest.TestCase):
    def setUp(self):
        app.config['TESTING'] = True
        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
        self.app = app.test_client()
        db.create_all()
    
    def tearDown(self):
        db.session.remove()
        db.drop_all()
    
    def test_home_page(self):
        response = self.app.get('/')
        self.assertEqual(response.status_code, 200)
        self.assertIn(b'Welcome', response.data)
    
    def test_api_posts(self):
        response = self.app.get('/api/posts')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content_type, 'application/json')

if __name__ == '__main__':
    unittest.main()

Deployment en Productie

Het deployen van Python web applicaties naar productie vereist verschillende overwegingen.

Gunicorn WSGI Server

# Installatie: pip install gunicorn
# Starten: gunicorn -w 4 -b 0.0.0.0:8000 app:app

# gunicorn_config.py
bind = "0.0.0.0:8000"
workers = 4
worker_class = "sync"
worker_connections = 1000
timeout = 30
max_requests = 1000
max_requests_jitter = 50
preload_app = True

Environment Variables

# config.py
import os

class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-secret-key'
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'sqlite:///app.db'
    SQLALCHEMY_TRACK_MODIFICATIONS = False

class DevelopmentConfig(Config):
    DEBUG = True

class ProductionConfig(Config):
    DEBUG = False

config = {
    'development': DevelopmentConfig,
    'production': ProductionConfig,
    'default': DevelopmentConfig
}

Beste Practices

  • Beveiliging: Gebruik altijd HTTPS, sanitize input, en implementeer proper authenticatie
  • Database: Gebruik migraties, connection pooling, en proper indexing
  • Caching: Implementeer caching voor betere prestaties
  • Logging: Implementeer uitgebreide logging voor debugging
  • Error Handling: Graceful error handling en user-friendly error pages
  • Testing: Schrijf unit tests en integration tests
  • Documentation: Documenteer uw API endpoints

Populaire Python Web Development Tools

  • Frameworks: Flask, Django, FastAPI, Pyramid
  • ORM: SQLAlchemy, Django ORM, Peewee
  • Testing: pytest, unittest, nose2
  • Deployment: Gunicorn, uWSGI, Nginx
  • Monitoring: Sentry, New Relic, Datadog

Conclusie

Python biedt krachtige tools en frameworks voor web development. Of u nu kiest voor de flexibiliteit van Flask of de feature-rijke Django, Python stelt u in staat om schaalbare, onderhoudbare web applicaties te bouwen. De rijke ecosystem en grote community maken Python een uitstekende keuze voor web development projecten van elke omvang.

Leer Web Development met Python

Onze web development cursus behandelt Flask, Django, en moderne deployment technieken.

Bekijk Web Development Cursussen