APLICACIONES CON FLASK ING.
RUBÉN SANABRIA
Un pequeño proyecto con Flask.
Los pasos a comenzar son:
Instalar el entorno virtual:
>pip install virtualenv
Para crear dentro de nuestro proyecto:
>Python –m venv virtual
El siguiente paso es activar el entorno virtual
Estando en la carpeta del proyecto;
>virtual/scripts/actívate
Se activa como se aprecia (virtual)
(virtual) PS D:\curso2022_01\flask\curso2\practica4>
Una vez que se haya activado la carpeta virtual, empezamos a bajar las librerías
correspondientes:
>pip install flask
>pip install flask-sqlalchemy
>pip install flask-script
>pip install flask-migrate
Luego crearíamos el proyecto con la siguiente estructura
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
Para corroborar las librerías que serán utilizadas en el proyecto, se digita:
>pip freeze > requiere.txt
Y el contenido de requiere.txt es la siguiente:
alembic==1.7.7
click==8.1.3
colorama==0.4.4
Flask==2.1.2
Flask-Migrate==3.1.0
Flask-Script==2.0.6
Flask-SQLAlchemy==2.5.1
greenlet==1.1.2
importlib-metadata==4.11.3
importlib-resources==5.7.1
itsdangerous==2.1.2
Jinja2==3.1.2
Mako==1.2.0
MarkupSafe==2.1.1
SQLAlchemy==1.4.36
Werkzeug==2.1.2
zipp==3.8.0
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
pues bien, al crear la aplicación app, debemos crear las carpetas controllers, models, static,
templates dentro de app
Los models:
Se tienen las clases user, post, follow
La clase User
from app import db
class User(db.Model):
__tablename__ = 'usuarios'
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(60))
clave = db.Column(db.String(10))
email = db.Column(db.String(100))
def __init__(self, name, clave, email):
self.name = name
self.clave = clave
self.email = email
La clase Post:
from app.models import user
class Post(db.Model):
__tablename__ = 'posts'
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(60))
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
id_user = db.Column(db.Integer, db.ForeignKey('usuarios.id'))
user = db.relationship('User', foreign_keys=id_user)
def __init__(self, name, id_user):
self.name = name
self.id_user = id_user
La clase Follow
from app import db
from app.models import user, post
class Follow(db.Model):
__tablename__ = 'follows'
id = db.Column(db.Integer, primary_key = True)
id_user = db.Column(db.Integer, db.ForeignKey('usuarios.id'))
user = db.relationship('User', foreign_keys=id_user)
id_post = db.Column(db.Integer, db.ForeignKey('posts.id'))
post = db.relationship('Post', foreign_keys=id_post)
def __init__(self, id, id_user, id_post):
self.id = id
self.id_user = id_user
self.id_post = id_post
Estos elementos son llamados en la clase __init__.py, que se encuentra en el proyecto app
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///stock.db'
app.config['SQLALCHEMY_TRACKING'] = False
app.config['SECRET_KEY'] = 'micodigosecreto'
db = SQLAlchemy(app)
from app.controllers import (default, userController)
from app.models import (user, post, follow)
db.create_all()
como resultado nos creara las tablas correspondientes con sus respectivas relaciones
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
la base de datos stock.db
El contenido de la clase run.py
from app import app
if __name__=='__main__':
app.run()
el contenido de controllers, de default.py
from app import app
@app.route("/")
def index():
return "hola como estan"
que en nuestro caso sirve como ejemplo en este momento.
La estructura del proyecto se vería de la siguiente forma:
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
La clase userController.py
from app import app, db
from flask import (render_template, url_for, request, session, redirect)
from app.models import user
from app.controllers import default
@app.route("/user")
def registrar_user():
return render_template("add_user.html")
@app.route("/agregar", methods=['GET','POST'])
def adduser():
if request.method == 'POST':
name = request.form.get('name')
login = request.form.get('login')
clave = request.form.get('clave')
email = request.form.get('email')
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
if name and login and clave and email:
usu = user.User(name, login, clave, email)
db.session.add(usu)
db.session.commit()
return redirect(url_for('index'))
@app.route("/borrar/<int:id>")
def delete_user(id):
usu = user.User.query.filter_by(id=id).first()
db.session.delete(usu)
db.session.commit()
usu = user.User.query.all()
return render_template('listausuario.html', usuario=usu)
@app.route("/editar/<id>", methods=["GET","POST"])
def edit_user(id):
usu = user.User.query.filter_by(id=id).first()
if request.method == "POST":
name = request.form.get('name')
login = request.form.get('login')
clave = request.form.get('clave')
email = request.form.get('email')
if name and login and clave and email:
usu.name = name
usu.login = login
usu.clave = clave
usu.email = email
db.session.commit()
return redirect( url_for('lista_user') )
return render_template("edita_user.html", usu=usu)
@app.route("/listauser")
def lista_user():
usuarios = user.User.query.all()
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
return render_template('listausuario.html', usuario=usuarios)
Ahora nos adentramos en la vista del proyecto que comprende las carpetas de:
El index.html lo vemos :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<center>
<h1>Index del sistema</h1>
<hr>
<p></p>
<a href="{{url_for('registrar_user')}}">Crud de Usuario</a><br>
<a href="#">Crud de Post</a><br>
<a href="#">Crud de Follow</a><br>
</center>
</body>
</html>
Que al ejecutar nos muestra una pantalla simple:
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
Al seleccionar Crud de Usuario nos lleva :
El add_user.html :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
table, th, td {
border: 1px solid white;
border-collapse: collapse;
}
th, td {
background-color: #96D4D4;
}
</style>
</head>
<body>
<form action="{{url_for('adduser')}}" method="post">
<center>
<h1>CRUD Usuario</h1>
<a href="{{url_for('index')}}">Volver al index</a>
<a href="{{url_for('lista_user')}}">Ver listado</a><br>
<hr>
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
<table >
<tr>
<td>Nombre :</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>Login :</td>
<td><input type="text" name="login"></td>
</tr>
<tr>
<td>Password :</td>
<td><input type="text" name="clave"></td>
</tr>
<tr>
<td>Email :</td>
<td><input type="text" name="email"></td>
</tr>
</table>
<input type="submit" value="Registrar">
</center>
</form>
<hr>
</body>
</html>
Y la vista del add_user
Al seleccionar Ver listado nos muestra la tabla correspondiente :
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
table, th, td {
border: 1px solid white;
border-collapse: collapse;
}
th, td {
background-color: #96D4D4;
}
</style>
</head>
<body>
<h3>Listado de usuarios</h3>
<a href="{{url_for('registrar_user')}}">Crud de Usuario</a><br>
<table style="width:90%">
<tr>
<th>ID</th>
<th>NOMBRE</th>
<th>LOGIN</th>
<th>CLAVE</th>
<th>EMAIL</th>
<th></th>
</tr>
{% for usu in usuario %}
<tr>
<td>{{ usu.id }}</td>
<td>{{ usu.name }}</td>
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
<td>{{ usu.login }}</td>
<td>{{ usu.clave }}</td>
<td>{{ usu.email }}</td>
<td>
<ahref="/borrar/{{ usu.id }}">Borrar</a>
<a href="/editar/{{ usu.id }}">Editar</a>
</td>
</tr>
{% endfor %}
</table>
</body>
</html>
Al darle Editar :
Nos lleva a la pantalla de editar usuario, si se quiere actualizar, los elementos
correspondientes.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
table,
th,
td {
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
border: 1px solid white;
border-collapse: collapse;
}
th,
td {
background-color: #96D4D4;
}
</style>
</head>
<body>
<center>
<h1>Edita Usuario</h1>
<a href="{{url_for('index')}}">Volver al index</a>
<a href="{{url_for('lista_user')}}">Ver listado</a><br>
<form action="#" method="post">
<hr>
<table>
<tr>
<td>Codigo :</td>
<td><input type="text" name="id" value="{{ usu.id }}"
readonly></td>
</tr>
<tr>
<td>Nombre :</td>
<td><input type="text" name="name" value="{{ usu.name }}"></td>
</tr>
<tr>
<td>Login :</td>
<td><input type="text" name="login" value="{{ usu.login }}"></td>
</tr>
<tr>
<td>Password :</td>
<td><input type="text" name="clave" value="{{ usu.clave }}"></td>
</tr>
<tr>
<td>Email :</td>
<td><input type="text" name="email" value="{{ usu.email }}"></td>
</tr>
</table>
<input type="submit" value="Actualizar">
</form>
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
</center>
<hr>
</body>
Podemos seguir con nuestro pequeño proyecto:
Le agregamos un
controlador de post
También en template
agregamos una carpeta
para poder ir
ordenandolos
Y así llegamos al controlador de postController.py
from app import app, db
from flask import (render_template, url_for, request, session, redirect)
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
from app.models import post
from app.controllers import default
@app.route("/post")
def registrar_post():
return render_template("/post/add_post.html")
@app.route("/agregarpost", methods=['GET','POST'])
def add_post():
if request.method == 'POST':
name = request.form.get('name')
user = request.form.get('id_user')
if name and user:
pst = post.Post(name, user)
db.session.add(pst)
db.session.commit()
return redirect(url_for('registrar_post'))
@app.route("/borrarpost/<int:id>")
def delete_post(id):
pst = post.Post.query.filter_by(id=id).first()
db.session.delete(pst)
db.session.commit()
pst = post.Post.query.all()
return render_template('/post/listapost.html', post=pst)
@app.route("/editarpost/<int:id>", methods=["GET","POST"])
def edit_post(id):
pst = post.Post.query.filter_by(id=id).first()
if request.method == "POST":
name = request.form.get('name')
user = request.form.get('id_user')
if name and user:
pst.name = name
pst.id_user = user
db.session.commit()
return redirect( url_for('lista_post') )
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
return render_template("/post/edita_post.html", post=pst)
@app.route("/listapost")
def lista_post():
pst = post.Post.query.all()
return render_template('/post/listapost.html', post=pst)
también debemos observer el __init__.py, del proyecto, donde :
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///stock.db'
app.config['SQLALCHEMY_TRACKING'] = False
app.config['SECRET_KEY'] = 'micodigosecreto' Aquí se ponen los controllers
que se van agregando
db = SQLAlchemy(app)
from app.controllers import (default, userController, postController)
from app.models import (user, post, follow)
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db.create_all()
En el parte de la vista vemos que add_post.html;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
table, th, td {
border: 1px solid white;
border-collapse: collapse;
}
th, td {
background-color: #96D4D4;
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
}
</style>
</head>
<body>
<form action="{{url_for('add_post')}}" method="post">
<center>
<h1>Agrega Post</h1>
<a href="{{url_for('index')}}">Volver al index</a>
<a href="{{url_for('lista_post')}}">Ver listado</a><br>
<hr>
<table >
<tr>
<td>Nombre :</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>Codigo User :</td>
<td><input type="text" name="id_user"></td>
</tr>
</table>
<input type="submit" value="Registrar">
</center>
</form>
<hr>
</body>
</html>
El edita_post.html, tenemos la siguiente codificación
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
table,
th,
td {
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
border: 1px solid white;
border-collapse: collapse;
}
th,
td {
background-color: #96D4D4;
}
</style>
</head>
<body>
<center>
<h1>Edita Post</h1>
<a href="{{url_for('index')}}">Volver al index</a>
<a href="{{url_for('lista_post')}}">Ver listado</a><br>
<form action="#" method="post">
<hr>
<table>
<tr>
<td>Codigo :</td>
<td><input type="text" name="id" value="{{ post.id }}"
readonly></td>
</tr>
<tr>
<td>Nombre :</td>
<td><input type="text" name="name" value="{{ post.name
}}"></td>
</tr>
<tr>
<td>Login :</td>
<td><input type="text" name="id_user" value="{{
post.id_user }}"></td>
</tr>
</table>
<input type="submit" value="Actualizar">
</form>
</center>
<hr>
</body>
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
El listapost.html, es el formato de visualización:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
table,
th,
td {
border: 1px solid white;
border-collapse: collapse;
}
th,
td {
background-color: #96D4D4;
}
</style>
</head>
<body>
<h3>Listado de Post</h3>
<a href="{{url_for('registrar_post')}}">Crud de Post</a><br>
<table style="width:90%">
<tr>
<th>ID</th>
<th>NOMBRE</th>
<th>USUARIO</th>
<th></th>
</tr>
{% for p in post %}
<tr>
<td>{{ p.id }}</td>
<td>{{ p.name }}</td>
<td>{{ p.id_user }}</td>
<td>
<a href="/borrarpost/{{ p.id }}">Borrar</a>
<a href="/editarpost/{{ p.id }}">Editar</a>
</td>
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
</tr>
{% endfor %}
</table>
</body>
</html>
El resultado sería:
Se ha cambiado el default, y también le hemos agregado elementos de css, con Jinja2, para
encontrar el camino de los archivos staticos.
from app import app
from flask import render_template, url_for
@app.route("/")
def index():
# return render_template("index.html")
return render_template("login.html")
el login.html:
APLICACIONES CON FLASK ING. RUBÉN SANABRIA
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link type="text/css" rel="stylesheet"
href="{{url_for('static',filename='css/login.css')}}" />
<link type="text/css" rel="stylesheet"
href="{{url_for('static',filename='css/bootstrap.min.css')}}" />
</head>
<body>
<form id="form1">
<section class="form-login">
<h5>Sistema de Inventario</h5><br />
Login :<br />
<div class="input-group">
<span class="input-group-text"></span>
<input type="text" class="form-control" placeholder="ingrese
Login">
</div>
Password : <br />
<div class="input-group">
<span class="input-group-text"></span>
<input type="password" class="form-control"
placeholder="ingrese Password">
</div>
<br />
<button type="button" class="btn btn-primary">Ejecutar</button>
</section>
</form>
</body>
</html>
Podemos observar que utilizamos bootstrap, en el archivo static, u otro archivo css propio
del login. Al ejecutar dicho html, nos muestra..
APLICACIONES CON FLASK ING. RUBÉN SANABRIA