Solucionado (ver solução)
Solucionado
(ver solução)
9
respostas

Falha no upload de arquivos.

Caros, bom dia!

Estou tentando fazer o Mãos na massa... da aula 03 e embarrerei no passo 06, onde estou obtendo o erro:

FileNotFoundError: [Errno 2] No such file or directory: "~/Documentos/alura/curso-flask/jogoteca/uploads/<FileStorage: 'fifa2018.jpg' ('image/jpeg')>"

Bem, o código da rota respectiva é:

...
@app.route('/cadastrar', methods=['POST',])
def cadastrar():
    nome = request.form['nome']
    categoria = request.form['categoria']
    console = request.form['console']

    jogo = Jogo(nome, categoria, console)
    jogo_dao.salvar(jogo)

    arquivo = request.files['arquivo']
    upload_path = app.config['UPLOAD_PATH']
    arquivo.save("{0}/{1}".format(upload_path, arquivo))

    return(redirect(url_for('index')))
...

O do formulário é:

{% extends "template.html" %}
    {% block conteudo %}
        <form action="{{ url_for('cadastrar') }}" method="POST" enctype="multipart/form-data">
            <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>
                <div class="form-group">
                    <input type="file" name="arquivo" accept=".jpg">
                </div>
                <button type="submit" class="btn btn-primary btn-salvar">Salvar</button>
                <a class="btn btn-primary" href="{{ url_for('index') }}">Cancelar</a>
            </fieldset>
        </form>
    {% endblock %}

Alguma luz do que pode estar acontecendo? Pois não encontrei nada até o momento.

Agradeço e aguardo retorno.

9 respostas

Oi Adriano, tudo certo? O erro acusa não existir o diretório ou arquivo: "~/Documentos/alura/curso-flask/jogoteca/uploads/<FileStorage: 'fifa2018.jpg' ('image/jpeg')>"

Você possui essa imagem("fifa2018".jpg) na pasta /uploads?

Thais, boa tarde!

Bem, já não estou entendendo muito bem, mas não seria o método implementado que jogaria o arquivo que eu apontasse para o diretório em questão? Isso que não estou entendendo. Clico no botão para seleção do arquivo e, pensei eu, a aplicação faria 'upload' para o filesystem do servidor, armazenando o arquivo no diretório configurado por meio do UPLOAD_PATH.

Continuo no aguardo por alguma luz.

Perfeito Adriano, é isso mesmo já que você está cadastrando. O erro deve ter relação com o caminho, o diretório /upload. Poste o código de arquivo jogoteca.py pra eu dar uma olhada

Boa noite!

Primeiramente, me chamo Adriano e não Bruno. Segue o código solicitado:

import config
from flask import Flask, render_template, request, redirect, session, flash, url_for
from jogo import Jogo
from usuario import Usuario
from dao import JogoDao, UsuarioDao
from flask_mysqldb import MySQL

app = Flask(__name__)
app.secret_key="alura"

app.config['MYSQL_HOST']=config.flask_host
app.config['MYSQL_USER']=config.flask_user
app.config['MYSQL_PASSWORD']=config.flask_pswd
app.config['MYSQL_DB']=config.flask_db
app.config['MYSQL_PORT']=int(config.flask_port)

db = MySQL(app)
jogo_dao = JogoDao(db)
usuario_dao = UsuarioDao(db)

@app.route('/')
def index():
    lista = jogo_dao.listar()
    return(render_template("lista.html", titulo="Lista de Jogos", jogos=lista))

@app.route('/login')
def login():
    proxima = request.args.get('proxima')
    return(render_template('login.html', titulo="Faça seu Login", proxima=proxima))

@app.route('/autenticar', methods=['POST',])
def autenticar():
    usuario = usuario_dao.buscar_por_id(request.form['usuario'])
    if usuario:
        if usuario.senha == request.form['senha']:
            session['usuario_logado'] = usuario.id
            flash(usuario.nome + " logado com sucesso!")
            proxima_pagina = request.form['proxima']
            return(redirect(proxima_pagina))
    else:
        flash("Falha na autenticação!")
        return(redirect('login'))

@app.route('/logoff')
def logout():
    session['usuario_logado'] = None
    flash("Logoff efetuado com sucesso!")
    return(redirect('/'))

@app.route('/cadastro')
def cadastro():
    if 'usuario_logado' not in session or session['usuario_logado'] == None:
        return redirect(url_for('login', proxima = url_for('cadastro')))
    return(render_template("cadastro.html", titulo="Cadastro de Jogos"))

@app.route('/cadastrar', methods=['POST',])
def cadastrar():
    nome = request.form['nome']
    categoria = request.form['categoria']
    console = request.form['console']
    jogo = Jogo(nome, categoria, console)
    jogo_dao.salvar(jogo)
    return(redirect(url_for('index')))

@app.route('/editar/<int:id>')
def editar(id):
    if 'usuario_logado' not in session or session['usuario_logado'] == None:
        return redirect(url_for('login', proxima = url_for('atualizar')))
    jogo = jogo_dao.busca_por_id(id)
    return(render_template("editar.html", titulo="Atualização de Jogo", jogo=jogo))

@app.route('/atualizar', methods=['POST',])
def atualizar():
    nome = request.form['nome']
    categoria = request.form['categoria']
    console = request.form['console']
    jogo = Jogo(nome, categoria, console, id=request.form['id'])
    jogo_dao.salvar(jogo)
    return(redirect(url_for('index')))

@app.route('/deletar/<int:id>')
def deletar(id):
    if 'usuario_logado' not in session or session['usuario_logado'] == None:
        return redirect(url_for('login', proxima = url_for('deletar')))
    jogo_dao.deletar(id)
    return redirect(url_for('index'))

app.run(host="0.0.0.0", port=8080, debug=True)

Aguardo retorno.

Me desculpe, respondemos muitos alunos todos os dias e podemos acabar nos confundindo no nome vez ou outra na hora de responder.

Então Adriano, faltou você definir o caminho UPLOAD_PATH (passo 4 do Mãos na massa... que você citou).

Acrescente essa linha de código no seu arquivo jogoteca.py:

app.config['UPLOAD_PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/uploads'

logo abaixo de

app.config['MYSQL_PORT']=int(config.flask_port)

que deve funcionar.

Espero ter ajudado e bons estudos!

Bom dia!

Mesmo com a inserção, o erro persiste. Segue os trechos do código mais abaixo.

# Parâmetros de configuração
...
app.config['UPLOAD_PATH']=os.path.dirname(os.path.abspath(__file__)) + "/uploads"
...
# Rota para cadastro de um novo jogo.
@app.route('/cadastrar', methods=['POST',])
def cadastrar():
    nome = request.form['nome']
    categoria = request.form['categoria']
    console = request.form['console']

    jogo = Jogo(nome, categoria, console)
    jogo_dao.salvar(jogo)

    arquivo = request.files['arquivo']
    upload_path = app.config['UPLOAD_PATH']
    arquivo.save("{0}/{1}".format(upload_path, arquivo))

    return(redirect(url_for('index')))

Desde já, agradeço a atenção e aguardo retorno.

O código completo encontra-se no GitHub:

Senhores(as), boa tarde!

Nada?

solução!

Oi Adriano, desculpe a demora. Então, é o mesmo erro? Você terminou todos os passos do Mão na massa do capítulo 3?

A linha que pode estar gerando erro é esta:

    arquivo.save("{0}/{1}".format(upload_path, arquivo))

mude para:

     arquivo.save('{0}/{1}'.format(upload_path, arquivo.filename)

ou melhor, como feito no passo 7:

    arquivo.save('{0}/capa{1}.jpg'.format(upload_path, jogo.id)

Se ainda persistir o erro, poste aqui toda a stack trace gerada, por favor.