I am programming an online auction using flask. And I settled on the following problem: I do not know how to check if the auction has ended. On the main page there is a selection of the first 6 lots from the database and on each product card there is an end timer that is updated when the page is refreshed, but when the time comes to an end, the time value goes into a negative value. It is required to implement the logic of constant checking of the end of all auctions available in the database.
The best thing I came up with is Apscheduler which checks all auctions from the database every 10 seconds, and if it finds a lot whose end time and current time difference is less than 0, then is_active=False is assigned to such a lot, but it seems to me not very optimal. What should I do?
ROUTES.PY
from flask import redirect, request, render_template, flash, g, send_from_directory
from werkzeug.security import check_password_hash, generate_password_hash
from flask_login import login_user, current_user, logout_user
import datetime as dt
import jwt
import os
from main_app import app, db, UserForm, AuctionLotForm, mail, a_lot_photos
from main_app.models import User, AuctionLotModel
#.strftime("%d-%m-%YT%H:%M")
#Главная страница
#app.route('/')
def main_page():
lots = AuctionLotModel.query.all()
cur_time = dt.datetime.now().replace(microsecond=0)
return render_template('main_page.html', lots=lots, cur_time=cur_time)
# Регистрация
#app.route('/registration', methods=["POST", "GET"])
def registration():
form = UserForm()
if form.validate_on_submit():
real_name = form.real_name.data
username = form.username.data
date_of_birth = form.date_of_birth.data
email = form.email.data
password = form.password.data
hashed_password = generate_password_hash(password)
user = User(real_name=real_name, username=username, date_of_birth=date_of_birth, email=email, password=hashed_password)
db.session.add(user)
db.session.commit()
login_user(user)
token = jwt.encode(
{'username':username},
app.config['SECRET_KEY'],
algorithm = 'HS256'
)
mail.send(
subject='Подтверждение почты',
receivers=[email],
html_template='auth/email_confirmation.html',
body_params={
"token": token
}
)
return render_template('auth/check_email.html')
return render_template('auth/registration.html', form=form)
#подтверждеие почты
#app.route('/email_verification/<token>')
def email_verification(token):
data = jwt.decode(token, app.config['SECRET_KEY'], algorithms=["HS256"])
username = data['username']
user = User.query.filter_by(username=username).one_or_404()
user.email_is_verified = True
db.session.commit()
return render_template('auth/email_is_confirmed.html')
#Форма авторизиции
#app.route('/login', methods=["POST", "GET"])
def login():
email = request.form.get('email')
password = request.form.get('password')
if request.method == 'POST':
if not (email and password):
flash('Заполните все поля')
else:
user = db.session.query(User).filter(User.email == email).first()
if not (user and check_password_hash(user.password, password)):
flash('Неверное имя пользователя или пароль')
else:
login_user(user)
return redirect('/')
return render_template('auth/login.html')
#Выход из профиля
#app.route('/logout', methods=["POST", "GET"])
def logout():
logout_user()
return redirect('/')
#Добавление лота для аукциона
#app.route('/aal', methods=["POST", "GET"])
def photo_form():
form = AuctionLotForm()
if form.validate_on_submit():
cur_time = dt.datetime.now().replace(microsecond=0)
dir_name = 'img_folder' + str(os.urandom(6).hex())
i = 1
for photo in request.files.getlist('photos'):
a_lot_photos.save(photo, name=dir_name + '/' + str(i)+'.')
i += 1
new_auction_lot = AuctionLotModel(
a_lot_title=form.a_lot_title.data,
description=form.description.data,
base_price=form.base_price.data,
auction_duration=dt.timedelta(minutes=form.auction_duration.data),
end_date=cur_time + dt.timedelta(minutes=form.auction_duration.data),
photo_dir=dir_name,
)
db.session.add(new_auction_lot)
db.session.commit()
return redirect('/')
return render_template('add_auction_lot.html', form=form)
#Просмотр профиля лота
#app.route('/lot/<lot_id>')
def lot_view(lot_id):
lot = AuctionLotModel.query.filter_by(id=lot_id).one_or_404()
return render_template('a_lot_view.html', lot=lot)
#Обработка 404
#app.errorhandler(404)
def error(error):
return render_template('404.html')
#app.before_request
def before_request():
g.user = current_user
#Media folder custom endpoint
#app.route('/media/<path:filename>')
def media(filename):
return send_from_directory('media', filename)
MODELS.PY
from flask_login import UserMixin
from datetime import datetime
from main_app import db, manager
current_date = datetime.now().replace(microsecond=0)
class User(db.Model, UserMixin):
__tablename__ = 'users_table'
id = db.Column(db.Integer, primary_key=True)
#Обязательные поля
real_name = db.Column(db.String(40), nullable=False)
date_of_birth = db.Column(db.Date, nullable=False)
username = db.Column(db.String(30), nullable=False, unique=True)
email = db.Column(db.String(255), nullable=False, unique=True)
password = db.Column(db.String(255), nullable=False)
#Автозаполняющиеся поля
joining_date = db.Column(db.Date, nullable=False, default=current_date)
email_is_verified = db.Column(db.Boolean, nullable=False, default=False)
def __init__(self, real_name, date_of_birth, username, email, password):
self.real_name = real_name
self.date_of_birth = date_of_birth
self.username = username
self.email = email
self.password = password
#manager.user_loader
def user_loader(user_id):
return User.query.filter_by(id=user_id).first()
class LotModel(db.Model):
__tablename__ = 'lots_table'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(), nullable=False)
description = db.Column(db.Text(), nullable=False)
price = db.Column(db.Integer(), nullable=False)
date = db.Column(db.String(), nullable=False, default=current_date)
def __init__(self, title, description, price):
self.title = title
self.description = description
self.price = price
class AuctionLotModel(db.Model):
__tablename__ = 'auction_lots_table'
id = db.Column(db.Integer, primary_key=True)
a_lot_title = db.Column(db.String(), nullable=False)
description = db.Column(db.Text(), nullable=False)
base_price = db.Column(db.Integer(), nullable=False)
auction_duration = db.Column(db.Interval(), nullable=False)
photo_dir = db.Column(db.String(), nullable=False)
end_date = db.Column(db.DateTime(), nullable=False)
is_active = db.Column(db.Boolean, nullable=False, default=True)
current_bid = db.Column(db.Integer(), nullable=False, default=0)
date = db.Column(db.Date(), nullable=False, default=current_date)
def __init__(self, a_lot_title, description, base_price, auction_duration, photo_dir, end_date):
self.a_lot_title = a_lot_title
self.description = description
self.base_price = base_price
self.auction_duration = auction_duration
self.photo_dir = photo_dir
self.end_date = end_date
Related
I am writing an app that has 3 users: Super Admin, Admin, and Students. the Super Admin and Admin have the same functionalities except for some pages that are restricted for the admin, they have the same login credentials. (name and password ).
The student uses matricule number and password to log in.
Here is how I set the login_manager.login_view:
login = LoginManager()
login.login_views = 'admin.sperAdminLogin'
login.login_views = 'students.studentLogin'
However when I log in as a student it works, but when I open up a new window and access the super admin login page I am directly redirected to his home page without entering the credentials.
How can I set the login_view to handle this?
I am using flask blueprint I have an admin blueprint for both super admin and admin and a Student blueprint.
Here is my code :
The main init.py
from flask import Flask
from config import Config
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import MetaData
from flask_migrate import Migrate
from flask_login import LoginManager
db = SQLAlchemy()
migrate = Migrate()
login = LoginManager()
login.login_view = 'admin.sperAdminLogin'
login.login_view = 'students.studentLogin'
login.login_message = "Veuillez vous connecter pour accéder à cette page."
login.login_message_category = 'info'
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
db.init_app(app)
migrate.init_app(app, db, render_as_batch=True)
login.init_app(app)
# Registering blueprints
from sgp.errors import bp as errors_bp
app.register_blueprint(errors_bp)
from sgp.admin import bp as admin_bp
app.register_blueprint(admin_bp, url_prefix='/admin')
from sgp.students import bp as students_bp
app.register_blueprint(students_bp, url_prefix='/students')
from sgp.main import bp as bp
app.register_blueprint(bp)
return app
# Avoiding the circular import
from sgp import models
The model.py
from hashlib import md5
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import datetime
from flask import session
from flask_login import UserMixin
from sqlalchemy import ForeignKey
from sgp import db, login
class User(UserMixin, db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20),index=True, nullable=False)
first_name = db.Column(db.String(20), index=True, nullable=False)
last_name = db.Column(db.String(20), index=True, nullable=False)
email = db.Column(db.String(120), unique=True, index=True, nullable=False)
phone_number = db.Column(db.String(10), unique=True)
profile_pic = db.Column(db.String(20), nullable=False, default="default.jpg")
password_hash = db.Column(db.String(128), nullable=False)
status = db.Column(db.Boolean(), default=False)
type = db.Column(db.String(50))
__mapper_args__ = {
'polymorphic_identity':'user',
'polymorphic_on':type,
}
def set_password(self, password):
"""Take in self keyword and password and return the passwordhash"""
self.password_hash = generate_password_hash(password)
def check_password(self, password):
"""Take in self and password and returns True or false"""
return check_password_hash(self.password_hash, password)
class SuperAdmin(User):
__tablename__= 'superadmin'
id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
bordereaux = db.relationship("Bordereau", backref="superadmin", lazy="dynamic")
Payment_plans = db.relationship("PaymentPlan", backref="superadmin")
Payments = db.relationship("Payment", backref="superadmin", lazy="dynamic")
__mapper_args__ = {
'polymorphic_identity':'superadmin'
}
def __repr__(self):
"""
Takes in the keyword self and returns the instance of the super admin class
And it herited atributes
"""
return (
'Super-Admin, First-name %s, Last-name %s, Email %s'
'Gender %s, Login-time %s'
% (
self.first_name,
self.last_name,
self.email,
self.gender,
self.login_at,
)
)
class Student(User):
id : primary key & foreignkey
the id for the student user
gender : enum
the gender of the user
login_at : datetime
the login date and time the user was loged in to the system
date_of_birth : date
the date of birth of the user
creation_date : datetime
the date and time the use was created
student_matricule : int
the maricule of the student user
student_faculty : str
the faculty of the student
student_promotion : str
the promotion of the student user
"""
__tablename__= 'student'
id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
gender = db.Column(db.Enum("H", "F", "Au", name="varchar"))
login_at = db.Column(db.DateTime())
date_of_birth = db.Column(db.Date())
creation_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
matricule = db.Column(db.Integer, unique=True, nullable=False)
faculty = db.Column(db.String(20))
promotion = db.Column(db.String(20))
bordereaux = db.relationship("Bordereau", backref="student", lazy="dynamic")
__mapper_args__ = {
'polymorphic_identity':'student',
}
def avatar(self, size):
digest = md5(self.email.lower().encode('utf-8')).hexdigest()
return 'https://www.gravatar.com/avatar/{}?d=identicon&s={}'.format(
digest, size)
class AccademicYear(db.Model):
___tablename__ = 'accademic_year'
id = db.Column(db.Integer, primary_key=True)
starting_date = db.Column(db.Date(), nullable=False)
ending_date = db.Column(db.Date(), nullable=False)
bordereaux = db.relationship("Bordereau", backref="accademic_year", lazy="dynamic")
Payment_plans = db.relationship("PaymentPlan", backref="accademic_year", lazy="dynamic")
Payments = db.relationship("Payment", backref="accademic_year", lazy="dynamic")
class Bordereau(db.Model):
__tablename__ = 'bordereau'
id = db.Column(db.Integer, primary_key=True)
bordereau_code = db.Column(db.String(6), nullable=True)
bordereau_img = db.Column(db.String(20), nullable=False, default="bordereau.jpg")
payment_motif = db.Column(db.String(20), nullable=False)
timestamp = db.Column(db.DateTime())
Sending_time = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
super_admin_id = db.Column(db.Integer, db.ForeignKey("superadmin.id"))
student_id = db.Column(db.Integer, db.ForeignKey("student.id"))
accademic_year_id = db.Column(db.Integer, db.ForeignKey("accademic_year.id"))
class PaymentPlan(db.Model):
__tablename__ = 'paymentplan'
id = db.Column(db.Integer, primary_key=True)
payment_name = db.Column(db.String(20), unique=True, nullable=False)
payment_amount = db.Column(db.Numeric(), nullable=False)
payment_schadule = db.Column(db.Date(), nullable=False)
timestamp = db.Column(db.DateTime)
super_admin_id = db.Column(db.Integer, db.ForeignKey("superadmin.id"))
accademic_year_id = db.Column(db.Integer, db.ForeignKey("accademic_year.id"))
class Payment(db.Model):
__tablename__ = 'payment'
id = db.Column(db.Integer, primary_key=True)
matricule = db.Column(db.Integer, nullable=False)
amount = db.Column(db.Numeric(), nullable=False)
payment_motif = db.Column(db.String(20), nullable=False)
payment_type = db.Column(db.String(20), nullable=False)
carancy = db.Column(db.String())
register_time = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
timestamp = db.Column(db.DateTime)
super_admin_id = db.Column(db.Integer, db.ForeignKey("superadmin.id"))
accademic_year_id = db.Column(db.Integer, ForeignKey("accademic_year.id"))
#login.user_loader
def user_loader(id):
return User.query.get(id)
3.The super admin and student login form
class sperAdminLoginForm(FlaskForm):
"""A class to represent super admin login form"""
userName = StringField('Username',
validators=[DataRequired()])
# email = StringField('Email ou Username',
# validators=[DataRequired()])
password = PasswordField('password', validators=[DataRequired()])
# Secure cookie for keeping the user stay loged in for while
remember_me = BooleanField('Remember Me')
submit = SubmitField('Se connecter')
class studentLoginForm(FlaskForm):
"""A class to represent student login form"""
matricule = StringField('Matricule',
validators=[DataRequired()])
password = PasswordField('password', validators=[DataRequired()])
# Secure cookie for keeping the user stay loged in for while
remember = BooleanField('Remember Me')
submit = SubmitField('Se connecter')
i'm trying to make a jwt authentication, but every video and post that i see just use jsonify, none of them use render_template with login required, i searched a lot but didn't find anything that helps me, could you guys please help me to do this?
I want to after the user logging in correctly the next page check if the jwt it is correctly, if it is it will load the page, if it doesn't it won't load the page that is protectd with the login required decorator.
Bellow is the code. Thanks in advance.
from flask import Flask, render_template, redirect, url_for, jsonify, request, session, make_response
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired
import os
from flask_sqlalchemy import SQLAlchemy
import hashlib
from flask_login import LoginManager, UserMixin, login_required, login_user
import jwt
from datetime import datetime, timedelta
from functools import wraps
app = Flask(__name__)
app.config["SECRET_KEY"] = os.urandom(12)
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:Bambam&xx12#localhost/mobbi"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
login_manager = LoginManager(app)
login_manager.login_view = "render_login"
class LoginForm(FlaskForm):
login = StringField("Login", validators=[DataRequired()])
senha = PasswordField("Senha", validators=[DataRequired()])
botao_entrar = SubmitField("Entrar")
class Usuarios(db.Model, UserMixin):
__tablename__ = "usuarios"
id = db.Column(db.Integer, primary_key=True)
p_nome = db.Column(db.String(50), nullable=False)
u_nome = db.Column(db.String(50), nullable=False)
login = db.Column(db.String(50), nullable=False)
senha_hash = db.Column(db.String(255), nullable=False)
cargos = db.relationship("CargosUsuarios", backref="usuarios")
def __repr__(self):
return f"<Usuário: {self.id}>"
class Cargos(db.Model):
__tablename__ = "cargos"
id = db.Column(db.Integer, primary_key=True)
nome = db.Column(db.String(50), nullable=False)
descricao = db.Column(db.Text, nullable=False)
usuarios = db.relationship("CargosUsuarios", backref="cargos")
permissoes = db.relationship("PermissoesCargos", backref="cargos")
def __repr__(self):
return f"<Cargo: {self.id}>"
class Permissoes(db.Model):
__tablename__ = "permissoes"
id = db.Column(db.Integer, primary_key=True)
nome = db.Column(db.String(50), nullable=False)
descricao = db.Column(db.Text, nullable=False)
cargos = db.relationship("PermissoesCargos", backref="permissoes")
def __repr__(self):
return f"<Permissão: {self.id}>"
class CargosUsuarios(db.Model):
__tablename__ = "cargos_usuarios"
id = db.Column(db.Integer, primary_key=True)
id_usuario = db.Column(db.Integer, db.ForeignKey("usuarios.id"))
id_cargo = db.Column(db.Integer, db.ForeignKey("cargos.id"))
def __repr__(self):
return f"<Cargos Usuários: {self.id}>"
class PermissoesCargos(db.Model):
__tablename__ = "permissoes_cargos"
id = db.Column(db.Integer, primary_key=True)
id_cargo = db.Column(db.Integer, db.ForeignKey("cargos.id"))
id_permissao = db.Column(db.Integer, db.ForeignKey("permissoes.id"))
def __repr__(self):
return f"<Permissões Cargos: {self.id}>"
#login_manager.user_loader
def load_user(user_id):
return Usuarios.query.get(int(user_id))
def token_required(func):
#wraps(func)
def decorated(*args, **kwargs):
token = session.get("token")
try:
payload = jwt.decode(token, app.config["SECRET_KEY"])
print("Alerta: Token válido!")
except:
print("Alerta: Token inválido!")
#app.route("/", methods=["GET", "POST"])
#app.route("/login", methods=["GET", "POST"])
def render_login():
form = LoginForm()
if form.validate_on_submit():
login = form.login.data
senha = form.senha.data
senha_hash = hashlib.sha256(senha.encode()).hexdigest()
usuario = Usuarios.query.filter_by(login=login).first()
if usuario:
senha_check = usuario.senha_hash
if senha_hash == senha_check:
login_user(usuario)
cargos = []
permissoes = []
for cargo in usuario.cargos:
dados_cargo = Cargos.query.filter_by(id=cargo.id_cargo).first()
cargos.append(dados_cargo.nome)
for permissao in dados_cargo.permissoes:
dados_permissao = Permissoes.query.filter_by(id=permissao.id_permissao).first()
permissoes.append(dados_permissao.nome)
token = jwt.encode({
"usuario": login,
"cargos": cargos,
"permissoes": list(set(permissoes)),
"expiration": str(datetime.utcnow() + timedelta(seconds=120))
},
app.config["SECRET_KEY"]
)
return redirect(url_for("render_graficos"))
return render_template("login.html", form=form)
#app.route("/graficos")
#login_required
def render_graficos():
return render_template("graficos.html")
if __name__ == "__main__":
app.run(debug=True)
im learning about Flask and flask-sqlalchemy relationships. I have five tables Clientes, Solicitud, Cotizacion, Servicio, Asesor. Im trying to get Service cost for a specific Request (Solicitud) table but i dont get it, why i cant get this value for a specific id Request (Solicitud) in crearcotizacion view. The process is like this: A client is created, then a Service and a Asesor(Advisor) is created. Then in crearsolicitudes view, all clients are listed, click on crear solicitud plus button, and then the create request form appears, the data of the client and request all ok. When i try to create a new quotation (cotizacion) crearcotizacion view, i cant bring the cost of the service value that belongs to that request and service. I try to create a foreing key between request (Solicitud) and Servicio but it doesnt work.
My Model
class Clientes(db.Model):
__tablename__ = "clientes"
id = db.Column(db.Integer, primary_key=True)
nombres = db.Column(db.String(80), nullable=False)
apellidos = db.Column(db.String(80), nullable=False)
correo = db.Column(db.String(120), nullable=False)
empresa = db.Column(db.String(120), nullable=False)
celular = db.Column(db.String(50), nullable=False)
mensaje = db.Column(db.String(500), nullable=False)
checkbox = db.Column(db.Boolean, nullable=False)
cotizaciones = db.relationship('Cotizacion', backref='clientes_cotizan', lazy=True)
solicitudes = db.relationship('Solicitud', backref='sol_client', lazy=True)
servicios = db.relationship('Servicio', backref='clientes_servicios', lazy=True)
def __init__(self, nombres, apellidos, correo, empresa, celular, mensaje, checkbox, sol_client, clientes_servicios):
self.nombres = nombres
self.apellidos = apellidos
self.correo = correo
self.empresa = empresa
self.celular = celular
self.mensaje = mensaje
self.checkbox = checkbox
self.sol_client = sol_client
self.clientes_servicios = clientes_servicios
def __repr__(self):
return '<Clientes %r>' % self.id
class Solicitud(db.Model):
__tablename__ = "solicitud"
id = db.Column(db.Integer, primary_key=True)
servicio_campo = db.Column(db.String(120), nullable=False)
asesore = db.Column(db.String(120), nullable=False)
# LLAVE FORANEA
solicitud_cliente = db.Column(db.Integer, db.ForeignKey("clientes.id"), nullable=True)
solicitudes_cliente = db.relationship('Cotizacion', backref='clientes_solicitan', lazy=True)
solicitudes_servicio = db.relationship('Servicios', backref='solicitud_servicios', lazy=True)
def __init__(self, servicio_campo, asesore, sol_client, clientes_servicios):
self.servicio_campo = servicio_campo
self.asesore = asesore
self.sol_client = sol_client
self.clientes_servicios = clientes_servicios
class Cotizacion(db.Model):
__tablename__ = "cotizacion"
id = db.Column(db.Integer, primary_key=True)
numero_horas = db.Column(db.Integer, nullable=False)
descuento = db.Column(db.Integer, nullable=False)
valor_total = db.Column(db.Integer, nullable=False)
# LLAVE FORANEA
cliente_id = db.Column(db.Integer, db.ForeignKey("clientes.id"), nullable=True)
solicitud_id = db.Column(db.Integer, db.ForeignKey("solicitud.id"), nullable=True)
def __init__(self, numero_horas, descuento, valor_total, clientes_cotizan, clientes_solicitan):
self.numero_horas = numero_horas
self.descuento = descuento
self.valor_total = valor_total
self.clientes_cotizan = clientes_cotizan
self.clientes_solicitan = clientes_solicitan
def __repr__(self):
return '<Cotizacion %r>' % self.id
class Servicio(db.Model):
__tablename__ = "servicio"
id = db.Column(db.Integer, primary_key=True)
nombre_servicio = db.Column(db.String(120), nullable=False)
costo_servicio = db.Column(db.Integer, nullable=False)
# LLAVE FORANEA
cliente_id = db.Column(db.Integer, db.ForeignKey("clientes.id"), nullable=True)
solicitud_id = db.Column(db.Integer, db.ForeignKey("solicitud.id"), nullable=True)
def __init__(self, nombre_servicio, costo_servicio, clientes_servicios, solicitud_servicios):
self.nombre_servicio = nombre_servicio
self.costo_servicio = costo_servicio
self.clientes_servicios = clientes_servicios
self.solicitud_servicios = solicitud_servicios
class Asesor(db.Model):
__tablename__ = "asesor"
id = db.Column(db.Integer, primary_key=True)
primernombre_asesor = db.Column(db.String(120), nullable=False)
apellido_asesor = db.Column(db.String(120), nullable=False)
correo_asesor = db.Column(db.String(150), nullable=False)
def __init__(self, primernombre_asesor, apellido_asesor, correo_asesor, asesor_client):
self.primernombre_asesor = primernombre_asesor
self.apellido_asesor = apellido_asesor
self.correo_asesor = correo_asesor
self.asesor_client = asesor_client
My Views
#app.route('/cotizacion/crear/<int:id>', methods=("GET", "POST"))
#login_required
def crearcotizacion(id):
datos_solicitud = (db.session.query(Solicitud).filter_by(id=id).first())
datos_clientes = datos_solicitud.sol_client
datos_servicio = (db.session.query(Solicitud, Servicio.costo_servicio).join(Servicio).filter_by(id=id).first())
print(datos_servicio)
form = creacion_Cotizacion(request.form)
if current_user.role == True:
if request.method == 'POST':
cotizan = Cotizacion(
numero_horas=form.numero_horas.data,
descuento=form.descuento.data,
clientes_cotizan=datos_clientes,
clientes_solicitan=datos_solicitud,
clientes_servicios=datos_solicitud
)
db.session.add(cotizan)
db.session.commit()
flash('La cotización ha sido creado exitosamente', 'success')
return render_template('crearcotizacion.html', form=form, id=id, datos_solicitud=datos_solicitud, datos_clientes=datos_clientes, datos_servicio=datos_servicio)
else:
abort(401)
return render_template('crearcotizacion.html', nombres=current_user.nombres, correo=current_user.correo, role=current_user.role, id=id, form=form, datos_solicitud=datos_solicitud, datos_clientes=datos_clientes, datos_servicio=datos_servicio)
#app.route('/crearsolicitudes/crear/<int:id>', methods=("GET", "POST"))
#login_required
def crearsolicitud(id):
client = (db.session.query(Clientes).filter_by(id=id).one())
form = form_solicitudes(request.form)
datos_solicitud = (db.session.query(Solicitud).filter_by(id=id).first())
if current_user.role == True:
if request.method == 'POST':
solicitan = Solicitud(
servicio_campo = form.servicio_campo.data,
asesore = form.asesore.data,
sol_client = client,
clientes_servicios=datos_solicitud
)
db.session.add(solicitan)
db.session.commit()
message = f"La solicitud {solicitan.id} ha sido creada exitosamente"
flash(message, 'success')
return redirect(url_for('versolicitudes', client=client, id=id, form=form, nombres=current_user.nombres, correo=current_user.correo, role=current_user.role,))
else:
abort(401)
return render_template('crearsolicitudes.html', nombres=current_user.nombres, correo=current_user.correo, role=current_user.role, id=id, client=client, form=form)
#app.route('/crearcliente', methods=("GET", "POST"))
#login_required
def crearcliente():
clint = db.session.query(Clientes).filter_by(id=id).first()
form = creacion_Cliente(request.form)
client= Clientes(
nombres=form.nombres.data,
apellidos=form.apellidos.data,
correo=form.correo.data,
empresa=form.empresa.data,
celular=form.celular.data,
mensaje = form.mensaje.data,
checkbox = form.checkbox.data,
sol_client = clint,
clientes_servicios = clint)
if current_user.role == True:
if request.method == 'POST':
db.session.add(client)
db.session.commit()
message = f"El cliente {client.nombres} {client.apellidos} ha sido creado exitosamente"
flash(message, 'success')
return redirect(url_for('listarclientes', form=form))
else:
abort(401)
return render_template('crearcliente.html', form=form, nombres=current_user.nombres, correo=current_user.correo, role=current_user.role)
#app.route('/ver-solicitudes')
#login_required
def versolicitudes():
if current_user.role == True:
clientes= db.session.query(Solicitud.id, Solicitud.servicio_campo, Solicitud.asesore, Clientes.nombres, Clientes.apellidos, Clientes.correo, Clientes.empresa, Clientes.mensaje, Clientes.celular).join(Clientes).all()
return render_template('listacotizacion.html', clientes=clientes, nombres=current_user.nombres, correo=current_user.correo)
I know this has been asked several times but I've tried different solutions and it doesn't seem to be working. The "hash" is being stored in my DB and I can see that correctly, but when I'm comparing it, it always returns False.
The console shows:
TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement.
Here's my code:
routes.py
#api.route('/signup', methods=['POST'])
def signup():
body = request.get_json()
password = body["password"]
password_bytes = password.encode('utf-8')
if len(password_bytes) > 72:
password_bytes = base64.b64encode(hashlib.sha256(password_bytes).digest())
hashed = bcrypt.hashpw(password_bytes, bcrypt.gensalt())
hashed_str = hashed.decode('ascii')
User.create_user(body["name"], body["lastname"],
body["email"], hashed_str)
return jsonify({}), 200
#api.route("/login", methods=["POST"])
def login():
body = request.get_json()
email = body["email"]
password = body["password"]
password_bytes = password.encode('utf-8')
user = User.get_with_email(email)
hashed_str = user.password
if user is None:
raise APIException("Incorrect details")
if len(password_bytes) > 72:
password_bytes = base64.b64encode(hashlib.sha256(password_bytes).digest())
valid = bcrypt.checkpw(password_bytes, hashed_str.encode('ascii'))
print(valid)
if(valid == True):
access_token = create_access_token(identity = user.id)
return jsonify({"access_token": access_token})
models.py
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(120), unique=False, nullable=False)
lastname = db.Column(db.String(120), unique=False, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
password = db.Column(db.Text, unique=False, nullable=False)
is_active = db.Column(db.Boolean(), unique=False, nullable=False)
token = db.Column(db.String(254), unique=True, nullable=True)
propiedades = db.relationship('Propiedad', back_populates="user")
#classmethod
def create_user(cls, name, lastname, email, hashed_str):
user = cls()
user.name = name
user.lastname = lastname
user.email = email
user.password = hashed_str
user.is_active = True
db.session.add(user)
db.session.commit()
I'm writing APIs in flask, and i'm asking myself if i use SQLAlchemy in a functional but wrong way.
Currently my app is like
# File app.__init__.py
db = SQLAlchemy()
app = Flask(__name__, instance_relative_config=False)
def create_app():
app.config.from_object("config.Config")
CORS(app)
db.init_app(app)
So i don't initialize any engine.
# File app.core.core.py
from flask import current_app
from app import db
...
# Blueprint Configuration
core_bp = Blueprint("core_bp", __name__)
# Swagger documentation configuration
authorizations = {"apikey": {"type": "apiKey", "in": "header", "name": "Authorization"}}
api = Api(core_bp, authorizations=authorizations)
ns = api.namespace("auth", description="User Authentification APIs")
...
#ns.route("/signup", methods=["POST"])
class SignupApi(Resource):
"""
Enpoint for sign up of users
"""
#api.expect(resource_fields_signup)
#api.doc(
responses={400: "error", 201: "error",}
)
def post(self):
json_data = request.get_json()
if not json_data:
return make_response(jsonify({"error": "no data"}), 400)
...
user = User(email=email,role=role,confirmed=confirmed,password=password,first_name=first_name, last_name=last_name, tel_number=tel_number_formatted,active=active)
try:
db.session.add(user)
db.session.commit()
except:
return make_response(
jsonify({"error": "cant't add user to data base"}), 400
)
return make_response(
jsonify(
{
"success": "user created, mail confirmation sent",
"User id": user.id,
"User email": user.email,
}
),
201,
)
...
# File app.core.models.py
from app import db
from app import bcrypt
from flask_bcrypt import generate_password_hash, check_password_hash
import datetime
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String, unique=True, nullable=False)
first_name = db.Column(db.String, nullable=False)
last_name = db.Column(db.String, nullable=False)
password_hash = db.Column(db.String, nullable=False)
registered_on = db.Column(db.DateTime, nullable=False)
active = db.Column(db.Boolean, nullable=False)
admin = db.Column(db.Boolean, nullable=False, default=False)
tel_number = db.Column(db.String, nullable=False)
confirmed = db.Column(db.Boolean, nullable=False, default=False)
confirmed_on = db.Column(db.DateTime, nullable=True)
role = db.Column(db.String, nullable=False)
password_reset_date = db.Column(db.DateTime, nullable=True)
last_login_on = db.Column(db.DateTime, nullable=True)
def __init__(
self,
email,
first_name,
last_name,
password,
confirmed,
active,
role,
tel_number,
admin=False,
confirmed_on=None,
):
self.email = email
self.first_name = first_name
self.last_name = last_name
self.password_hash = bcrypt.generate_password_hash(password).decode("utf-8")
self.registered_on = datetime.datetime.now()
self.admin = admin
self.tel_number = tel_number
self.role = role
self.confirmed = confirmed
self.confirmed_on = confirmed_on
self.active = active
def hash_password(self, password):
self.password_hash = bcrypt.generate_password_hash(password).decode("utf-8")
def check_password(self, password):
return check_password_hash(self.password_hash, password)
def __repr__(self):
return "<User {}>".format(self.email)
It works, but i had some errors with DB, which i can't repeat. So where my question is.
I use
db.session.add(user)
db.session.commit()
And for queries:
user = User.query.filter_by(email=email).first_or_404()
Must I use engine? Why? because it works without difining engine.. Must i use connections?
I found the official documentation (https://docs.sqlalchemy.org/en/13/core/engines_connections.html) , but i don't really understand if it is necessary and what is the right way to use connections.