Fiz uns ajustes no código do projeto jogoteca, para gravar arquivos de imagem diretamente na base de dados e recuperar essas imagens da base de dados e exibi-las em uma página, pesquisei muito mas não achei um exemplo completo, só encontrei partes de códigos que fui montando, funcionou mas não sei se a forma que fiz é a melhor ou se tem outro jeito melhor para fazer isso.
Segue aqui os trechos de código que fazem o processo de gravar imagens em banco de dados e depois recuperá-las para serem exibidas:
models.py
class Jogos(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
nome = db.Column(db.String(50), nullable=False)
categoria = db.Column(db.String(40), nullable=False)
console = db.Column(db.String(20), nullable=False)
# Campo imagem
imagem = db.Column(db.LargeBinary, nullable=True)
def __repr__(self):
return '<Name %r>' % self.name
views.py
from flask import render_template, request, redirect, session, flash, url_for
from jogoteca import app, db
from models import Jogos, Usuarios
# os imports abaixos foram feitos para lidar com as imagens
from io import BytesIO
import base64
import io
@app.route('/criar', methods=['POST',])
def criar():
nome = request.form['nome']
categoria = request.form['categoria']
console = request.form['console']
# Aqui pego o arquivo carregado na página novo.html
# E jogo na variavel "file" que é do tipo <class 'werkzeug.datastructures.file_storage.FileStorage'>
file = request.files['arquivo']
# Aqui é feito o read() do arquivo para variavel imagem.
# O file.read() irá retornar a imagem no formato de bytes para ser inserida no campo imagem da tabela jogos
imagem = file.read()
jogo = Jogos(nome=nome, categoria=categoria, console=console, imagem=imagem)
db.session.add(jogo)
db.session.commit()
return redirect(url_for('lista'))
@app.route('/lista')
def lista():
if session["usuario_logado"] != None:
flash(f'Usuário {session["usuario_logado"]} logado com sucesso!!!', 'info')
# Aqui é feita a parte de busca dos jogos e o decode do arquivo de imagem
lista_jogos = Jogos.query.order_by(Jogos.id)
lista = []
for jogo in lista_jogos:
if jogo.imagem != None:
jogo.imagem = base64.b64encode(io.BytesIO(jogo.imagem).getvalue()).decode()
lista.append(jogo)
return render_template('lista.html',titulo='Lista de Jogos', jogos=lista)
else:
flash(f'Usuário não esta logado!!!', 'error')
session["rota"] = 'lista'
return redirect(url_for('login'))
...
novo.html
{% extends "template.html" %}
{% block conteudo %}
<form action="{{ url_for('criar') }}" method="post" enctype="multipart/form-data">
<input type="file" name="arquivo" accept=".jpeg, .jpg">
<fieldset>
<div class="form-group">
<label for="nome">Nome</label>
<input type="text" id="nome" name="nome" class="form-control">
</div>
<div class="form-group">
<label for="categoria">Categoria</label>
<input type="text" id="categoria" name="categoria" class="form-control">
</div>
<div class="form-group">
<label for="console">Console</label>
<input type="text" id="console" name="console" class="form-control">
</div>
<button type="submit" class="btn btn-primary btn-salvar">Salvar</button>
</fieldset>
</form>
{% endblock %}
lista.html
{% extends "template.html" %}
{% block conteudo %}
<table class="table table-striped table-responsive table-bordered">
<thead class="thead-default">
<tr>
<th align="left">Capa</th>
<th align="left">Nome</th>
<th align="left">Categoria</th>
<th align="left">Console</th>
<th align="center" colspan="2">Ações</th>
</tr>
</thead>
<tbody>
{% for jogo in jogos%}
<tr>
<td width="15%"><img src="data:image/jpeg;base64,{{ jogo.imagem }}" class="img-fluid img-thumbnail" width="100" height="200" onerror="this.style.display='none'"></td>
<td>{{ jogo.nome }}</td>
<td>{{ jogo.categoria }}</td>
<td>{{ jogo.console }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}