Upload
francisco-souza
View
3.487
Download
1
Embed Size (px)
DESCRIPTION
Apresentação interna feita na Giran (http://www.giran.com.br) sobre o Flask, microframework Python para construção de aplicações web.
Citation preview
FlaskMicroframework para construção de
aplicações web em Python
Francisco Souza@franciscosouzafrancisco@franciscosouza.netwww.franciscosouza.com.br
Micro?
http://www.flickr.com/photos/waisian/3590682463/
http://www.flickr.com/photos/benchilada/2467374335/
Mais um framework?
Por que usar um microframework?
Simplicidade
http://www.flickr.com/photos/payayita/3313899667/
é
simples.
mas o
django helloworld
3 comandos2 linhas de configuração3 linhas de código
Bônus
http://www.flickr.com/photos/malingering/58838080/
Flexibilidade
http://www.flickr.com/photos/wainwright/351684037/
from flask import Flask
app = Flask('hello')
@app.route('/hello')def hello(): return 'Hello world'
app.run()
Simples,leve e
pequeno.
Não subestime os pequenos
http://www.flickr.com/photos/st3f4n/4406339573/
Flask não é full stack
Acoplamento
http://www.flickr.com/photos/inertiacreeps/1414772429/
Deixe um framework de persistência cuidar do seu banco de dados...
Deixe um framework de persistência cuidar do seu banco de dados...
seja lá qual for seu banco de dados.
Deixe um framework de persistência cuidar do seu banco de dados...
seja lá qual for seu banco de dados.
Extensível
Extensões para...FormuláriosBancos de dadosTestesi18n CachingCSRFTemplating...
http://www.flickr.com/photos/ntrlwmn/4103357982/
Bônus!
Um CRUD cairia bem...
$ pip install Flask Flask-WTF Flask-SQLAlchemy$ mkdir projetos$ cd projetos$ mkdir templates$ touch projetos.py
Um CRUD cairia bem...
$ pip install Flask Flask-WTF Flask-SQLAlchemy$ mkdir projetos$ cd projetos$ mkdir templates$ touch projetos.py
Criação da aplicação
from flask import Flask
app = Flask(__name__)
Banco de dados, com SQLAlchemy
from flaskext.sqlalchemy import SQLAlchemy
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///dados.sqlite3'db = SQLAlchemy(app)
class Projeto(db.Model): __tablename__ = 'projetos' id = db.Column(db.Integer, primary_key = True) nome = db.Column(db.String(100), nullable = False) descricao = db.Column(db.Text, nullable = False)
Formulários, com WTForms
from flaskext import wtf
app.config['SECRET_KEY'] = 'HSAOIHs8ashw8JSJ'app.config['CSRF_ENABLED'] = Trueapp.config['CSRF_SESSION_KEY'] = 'HSAOIHs8ashw8JSJwtforms'
class ProjetoForm(wtf.Form): nome = wtf.TextField(u'Nome', validators=[wtf.Required()]) descricao = wtf.TextAreaField(u'Descrição',
validators=[wtf.Required()])
Formulários a partir de
modelos
http://www.flickr.com/photos/cayusa/981372736/
View para exibição do formulário
from flask import render_template
@app.route('/novo_projeto')def novo_projeto(): formulario = ProjetoForm() return render_template('novo_projeto.html', form=formulario)
Template, com Jinja2
<html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> <title>Novo projeto</title> </head> <body id=""> <h1 id="">Cadastro de novo Projeto</h1> <form action="" method="post" accept-charset="utf-8"> {{ form.csrf_token }} <p><label for="nome">{{ form.nome.label }}:</label><br /> {{ form.nome() }}</p> <p><label for="descricao">{{ form.descricao.label }}:</label><br /> {{ form.descricao() }}</p> <p><input type="submit" value="Cadastrar"/></p> </form> </body></html>
Template, com Jinja2
<html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> <title>Novo projeto</title> </head> <body id=""> <h1 id="">Cadastro de novo Projeto</h1> <form action="" method="post" accept-charset="utf-8"> {{ form.csrf_token }} <p><label for="nome">{{ form.nome.label }}:</label><br /> {{ form.nome() }}</p> <p><label for="descricao">{{ form.descricao.label }}:</label><br /> {{ form.descricao() }}</p> <p><input type="submit" value="Cadastrar"/></p> </form> </body></html>
Don't repeat yourself!
● Jinja2 macros
Macro para renderizar campo do formulário
{% macro render_field(field) %} <p><label for="{{ field.id }}">{{ field.label }}:<br /> {{ field(**kwargs)|safe }} {% if field.errors %} <ul class="errors"> {% for error in field.errors %} <li>{{ error }}</li> {% endfor %} </ul> {% endif %} </p>{% endmacro %}
Template, com Jinja2
<html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> <title>Novo projeto</title> </head> <body id=""> <h1 id="">Cadastro de novo Projeto</h1> <form action="" method="post" accept-charset="utf-8"> {{ form.csrf_token }} <p><label for="nome">{{ form.nome.label }}:</label><br /> {{ form.nome() }}</p> <p><label for="descricao">{{ form.descricao.label }}:</label><br /> {{ form.descricao() }}</p> <p><input type="submit" value="Cadastrar"/></p> </form> </body></html>
Template, com Jinja2 Macro
<html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> <title>Novo projeto</title> </head> <body id=""> <h1 id="">Cadastro de novo Projeto</h1> <form action="" method="post" accept-charset="utf-8"> {{ form.csrf_token }} {{ render_field(form.nome) }}
{{ render_field(form.descricao) }}
<p><input type="submit" value="Cadastrar"/></p> </form> </body></html>
Estendendo a view para receber dados do
formulário
from flask import render_template
@app.route('/novo_projeto')def novo_projeto(): formulario = ProjetoForm() return render_template('novo_projeto.html', form=formulario)
Estendendo a view para receber dados do
formulário
from flask import render_template
@app.route('/novo_projeto', methods = ['GET', 'POST'])def novo_projeto(): formulario = ProjetoForm() return render_template('novo_projeto.html', form=formulario)
RESTful URL routing
Utilíssimo para criação de APIs =)
RESTful URL routing
Utilíssimo para criação de APIs =)
Problemático para trabalhar com formulários.
HTML 5?
Estendendo a view para receber dados do
formulário
from flask import render_template
@app.route('/novo_projeto', methods = ['GET', 'POST'])def novo_projeto(): formulario = ProjetoForm() if formulario.validate_on_submit(): projeto = Projeto() projeto.nome = formulario.nome.data projeto.descricao = formulario.descricao.data db.session.add(projeto) db.session.commit() return redirect(url_for('listar_projetos')) return render_template('novo_projeto.html', form=formulario)
View para listagem dos projetos
@app.route('/projetos')def listar_projetos(): projetos = Projeto.query.all() return render_template('projetos.html', projetos=projetos)
Template para listagem
<html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> <title>Listagem de projetos</title> </head> <body id=""> <h1 id="">Listagem de projetos</h1> <ul> {% for projeto in projetos %} <li>{{ projeto.nome }}</li> {% endfor %} </ul> </body></html>
Template para listagem
<html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> <title>Listagem de projetos</title> </head> <body id=""> <h1 id="">Listagem de projetos</h1> <ul> {% for projeto in projetos %} <li>{{ projeto.nome }}</li> {% endfor %} </ul> </body></html>
Don't repeat yourself!
● Jinja2 macros● Herança de templates
Template base para herança
<html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> <title>{% block titulo %}{% endblock %}</title> </head> <body id=""> {% block conteudo %}{% endblock %} </body></html>
Template de formulário refatorado
{% extends "base.html" %}{% block titulo %} Cadastro de novo Projeto{% endblock %}
{% block conteudo %} <h1 id="">Cadastro de novo Projeto</h1> <form action="" method="post" accept-charset="utf-8"> {{ form.hidden_tag() }} {{ render_field(form.nome) }} {{ render_field(form.descricao) }} <p><input type="submit" value="Cadastrar"/></p> </form>{% endblock %}
Template de listagem refatorado
{% extends "base.html" %}{% block titulo %} Listagem de projetos{% endblock %}
{% block conteudo %} <h1 id="">Listagem de projetos</h1> <ul> {% for projeto in projetos %} <li>{{ projeto.nome }}</li> {% endfor %} </ul>{% endblock %}
Executando a aplicação
$ python projetos.py
E agora?
http://www.flickr.com/photos/smart-trips/4047872730/
E agora?
http://www.flickr.com/photos/smart-trips/4047872730/
flask.pocoo.org
E agora?
http://www.flickr.com/photos/smart-trips/4047872730/
flask.pocoo.org
werkzeug.pocoo.org
E agora?
http://www.flickr.com/photos/smart-trips/4047872730/
flask.pocoo.org
werkzeug.pocoo.org
jinja.pocoo.org/2
Francisco Souza@franciscosouza
www.franciscosouza.com.br