Flask - Exemples pratiques

Découvrez comment construire une application Flask complète à travers des exemples concrets.

Application de Blog

Structure du projet

blog/
├── app/
│   ├── __init__.py
│   ├── models.py
│   ├── routes.py
│   ├── forms.py
│   └── templates/
│       ├── base.html
│       ├── index.html
│       └── post.html
├── config.py
└── run.py

Modèles

# models.py
from app import db

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)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    author_id = db.Column(db.Integer, db.ForeignKey('user.id'))

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    posts = db.relationship('Post', backref='author')

Formulaires

# forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField
from wtforms.validators import DataRequired

class PostForm(FlaskForm):
    title = StringField('Titre', validators=[DataRequired()])
    content = TextAreaField('Contenu', validators=[DataRequired()])

Routes

# routes.py
@app.route('/')
def index():
    posts = Post.query.order_by(Post.created_at.desc()).all()
    return render_template('index.html', posts=posts)

@app.route('/post/new', methods=['GET', 'POST'])
@login_required
def new_post():
    form = PostForm()
    if form.validate_on_submit():
        post = Post(title=form.title.data,
                   content=form.content.data,
                   author=current_user)
        db.session.add(post)
        db.session.commit()
        return redirect(url_for('index'))
    return render_template('post_form.html', form=form)

API REST

# api.py
from flask import Blueprint, jsonify
from flask_restful import Resource, Api

api_bp = Blueprint('api', __name__)
api = Api(api_bp)

class PostAPI(Resource):
    def get(self, post_id):
        post = Post.query.get_or_404(post_id)
        return {
            'id': post.id,
            'title': post.title,
            'content': post.content,
            'author': post.author.username
        }

api.add_resource(PostAPI, '/posts/')

Tests API

# test_api.py
def test_get_post():
    response = client.get('/api/posts/1')
    assert response.status_code == 200
    data = response.get_json()
    assert 'title' in data
    assert 'content' in data

Templates

Base Template


<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    {% block content %}{% endblock %}
</body>
</html>

Page Template


{% extends "base.html" %}

{% block title %}{{ post.title }}{% endblock %}

{% block content %}
    <h1>{{ post.title }}</h1>
    <p>{{ post.content }}</p>
    <small>Par {{ post.author.username }}</small>
{% endblock %}

Extensions utiles

  • Flask-Login
    from flask_login import login_user
    
    @app.route('/login', methods=['POST'])
    def login():
        user = User.query.filter_by(
            username=form.username.data).first()
        if user and user.check_password(form.password.data):
            login_user(user)
            return redirect(url_for('index'))
  • Flask-Migrate
    from flask_migrate import Migrate
    
    migrate = Migrate(app, db)
    
    # Dans le terminal:
    # flask db init
    # flask db migrate
    # flask db upgrade