Flask
De Banane Atomic
Aller à la navigationAller à la recherche
Liens
- Flask Bootstrap
- Handling modal forms with Flask
- Bootstrap Edit table row
- Creating a Web App using Flask and Ajax
Exemple
mywebsite.py |
from flask import Flask, render_template app = Flask(__name__) @app.route('/') def index(): return render_template('index.html', title='Hello', text='Some text to display') if __name__ == '__main__': app.run(debug=True) |
templates/index.html |
<head> <link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}"> </head> <body> <h1>{{ title }}</h1> <p> {{ text }} </p> |
Jinja2
{{ my_variable }} {{ my_object.my_attribute }} {{ my_object.my_method() }} {% if my_variable > 0 %} {% elif my_variable < 10 %} {% else %} {% endif %} <a href="{{ url_for('my_page') }}">My Page</a> |
@app.route('/my-page-1') # nom de l'url libre, mais @app.route doit décorer la méthode def my_page(): # le nom de la méthode doit correspondre au nom utilisé dans url_for return 'My Page !!!' |
Héritage de templates
base.html |
<!-- définit un block vide ou non qui sera rempli, remplacé ou complété dans les templates enfants --> {% block content %} {% endblock %} |
my_page.html |
<!-- hérite du template parent --> {% extends "base.html" %} <!-- écrase le contenu du block content --> {% block content %} <p>Some text to display.</p> <!-- récupère le contenu du block du parent --> {{super()}} {% endblock %} |
Macros
my_macro.html |
{% macro render_field(field) %} <tr {% if field.errors %} class="error" {% endif %}> <td>{{ field.label }}</td> <td>{{ field(**kwargs)|safe }}</td> </tr> {% if field.errors %} <tr> <td></td> <td> <ul class="error"> {% for error in field.errors %} <li>{{ error }}</li> {% endfor %} </ul> </td> </tr> {% endif %} {% endmacro %} |
form.html |
{% from "my_macro.html" import render_field %} <form action="" method="post"> {{ form.hidden_tag() }} <table> {{ render_field(form.name, size=50) }} <tr> <td></td> <td><input type="submit" value="Ok"></td> </tr> </table> </form> |
Custom Filters
@app.template_filter('dateformat') def dateformat(value, format='%d %B %Y'): return value.strftime(format) |
{{ my_object.date|dateformat }} |
Route
@app.route('/') @app.route('/index') def index(): return render_template('index.html') @app.route('/my_page') def my_page(): return render_template('my_page.html') # POST @app.route('/formulaire', methods=('GET', 'POST')) def formulaire(): if request.method == 'POST': data = request.form['key'] # récupère l'élément key du formulaire return redirect(url_for('index')) # retour à index une fois le formulaire validé return render_template('formulaire.html') # affichage du formulaire @app.errorhandler(404) def page_not_found(e): return render_template('404.html'), 404 |
Flash messages
from flask import flash # configurer la clé secrète pour permettre l'utilisation de session app.config['SECRET_KEY'] = '...' # générer une clé de 24 octets: os.urandom(24) # enregistre un message dans la session flash('Some message.') |
<!-- Au chargement de la page, on récupère et affiche tous les messages --> <article> {% with messages = get_flashed_messages() %} {% if messages %} <ul> {% for message in messages %} <li>{{ message }}</li> {% endfor %} </ul> {% endif %} {% endwith %} </article> |
Flask-WTF 0.14.2
Liens
Flask-WTF Exemple
Penser à utiliser la macro render_field |
main.py |
from flask_wtf import FlaskForm from wtforms.fields import StringField, DateField, SelectField from wtforms.validators import DataRequired class MyForm(FlaskForm): name = StringField('The name:', validators=[DataRequired()], size=50) date = DateField('Date:', validators=[DataRequired()], format='%d %B %Y', size=50) country = SelectField('Country', coerce=int, validators=[DataRequired()], style='width:465px;') # coerc pour convertir la value str → int # pour la balise select, size définit le nombre d'éléments sélectionnable et non la longueur def __init__(self, *args, **kwargs): # permet de définir la liste de choix pour country super(MyForm, self).__init__(**kwargs) self.country.choices = [(k, v.name) for k, v in all_countries.items()] # (value, label) pairs def validate(self): # custom validation if self.name.data and self.name.data[0].isupper(): # test si le nom commence par une majuscule return super().validate() # appel les autres validateurs else: return False @app.route('/edit/<id>', methods=('GET', 'POST')) def edit(id): my_object = ... # récupère l'objet à éditer if request.method == 'GET': my_form = MyForm(obj=my_object) my_form.country.data = my_object.country.id_country else: my_form = MyForm() if my_form.validate_on_submit(): my_form.populate_obj(my_object) my_object.country = all_countries[my_object.country] # ici my_object.country est un int return redirect('index') # une fois le formulaire validé, redirection vers index return render_template('edit.html', id=id, form=my_form) |
edit.html |
<form action="" method="post"> {{ form.hidden_tag() }} <table class="table"> <tr> <td>{{ form.name.label }}</td> <td>{{ form.name(size = 50) }}</td> </tr> {% if field.errors %} <tr> <td></td> <td> <ul> {% for error in form.name.errors %} <li>{{ error }}</li> {% endfor %} </ul> </td> </tr> {% endif %} <tr> <td></td> <td> <a class="btn btn-default" href="{{ url_for('index') }}">Cancel</a> <input type="submit" class="btn btn-primary" value="Save changes"> </td> </tr> </table> </form> |
Flask-SQLAlchemy
from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' db = SQLAlchemy(app) class User(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) def __repr__(self): return '<User %r>' % self.username |
Flask-Bootstrap
|
from flask_bootstrap import Bootstrap app = Flask(__name__) Bootstrap(app) |
{% extends "bootstrap/base.html" %} {% block styles %} {{ super() }} <link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}"> {% endblock %} {% block title %}This is an example page{% endblock %} {% block content %} <h1>Hello, Bootstrap</h1> {% endblock %} {% block scripts %} {{ super() }} <script src="{{ url_for('static', filename='js/main.js') }}"></script> {% endblock %} |
Arborescence de fichiers
- mywebsite.py
- static
- css
- img
- js
- templates
- index.html
- 404.html
Model, Template, View
Nom | Équivalent MVC | Description |
---|---|---|
Model | Model | Classes business, stockage des données (SQLAlchemy) |
Template | View | Génération du HTML (Jinja2) |
View | Controller | Gestion des requêtes HTTP et envoie des réponses HTTP Routage et mapping des URL |
Flask-DebugToolbar
sudo pip install flask-debugtoolbar |
from flask_debugtoolbar import DebugToolbarExtension app = Flask(__name__) app.debug = True app.config['SECRET_KEY'] = b'...' app.config['DEBUG_TB_INTERCEPT_REDIRECTS'] = False toolbar = DebugToolbarExtension(app) |
Installation
pacman -S python-flask python-flask-wtf python-flask-sqlalchemy |