1
resposta

TypeError TypeError: join() argument must be str or bytes, not 'NoneType

Olá,

Estou conseguindo adicionar jogos com imagem normalmente, e editar também, mas sempre quando tento EDITAR um jogo que não possui imagem ainda, ele retorna o seguinte erro: "TypeError TypeError: join() argument must be str or bytes, not 'NoneType'"

Já li todo conteúdo e não consegui resolver o problema, será que alguém consegue me ajudar?

Obrigado!!

1 resposta

Oi Pedro, tudo bem?

Este erro é normal acontecer e é justamente pelo fato de não termos imagens cadastradas nestes jogos antigos, jogos nos quais foram disponibilizados pelo instrutor na criação do banco. E para corrigir isto, precisamos de fazer algumas verificações para saber se há ou não alguma imagem para aquele id que estamos tentando editar. Vamos por partes.

A primeira rota que precisaremos alterar será a de editar, pois, nela chamamos a função para recuperar uma imagem e nesta função, caso não exista uma imagem com aquele id, nos é retornado None :

@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('editar')))
    jogo = jogo_dao.busca_por_id(id)
    nome_imagem = recupera_imagem(id)
    if nome_imagem == None:
        return render_template('editar.html', titulo='Editando Jogo', jogo=jogo, capa_jogo = None)
    else:
        return render_template('editar.html', titulo='Editando Jogo', jogo=jogo
                               , capa_jogo=nome_imagem)

Observe que fazemos o teste para saber se o retorno da função recupera_imagem é None ou não. E caso seja, passamos na variável capa_jogo o valor de None para simbolizar que não possuímos uma imagem para aquele id. E caso a função recupera_imagem nos retorne algo, iremos passar o nome daquela imagem retornada.

Com isto, precisaremos alterar o nosso arquivo editar.html para que apareça a imagem somente se houver uma imagem, o que faz sentido. E como passamos para o arquivo editar.html a variável capa_jogo basta fazermos uma comparação, para saber se o valor desta variável é Noneou não. Pois, caso seja, não queremos mostrar o input de imagem no momento de editar. Certo?! Sendo assim, podemos usar a cláusula if e endif:

 {% if capa_jogo != None %}
    <figure class="thumb col-md-4">
        <img class="img-responsive" src="{{url_for('imagem', nome_arquivo=capa_jogo)}}">
        <figcaption>
            <label class="fileContainer">
                Mudar capa
                <input type="file" name="arquivo" accept=".jpg">
            </label>
        </figcaption>
    </figure>
    {% endif %}

Ou seja, caso seja diferente de None mostre o input da imagem.

Agora, precisamos passar o valor da variável capa_jogo, pois, ela nos será útil quando formos atualizar nossa edição:

<fieldset>
        <input type="hidden" name="capa_do_jogo" value="{{ capa_jogo }}">
        <input type="hidden" name="id" value="{{ jogo.id }}">

    codigo omitido ...
    </fieldset>

Ficou claro esta parte? Caso tenha ficado algum resquício de dúvida neste processo, fique a vontade para dar prosseguimento no tópico, tá?

Por fim, precisamos alterar a função atualizar, que é chamada quando salvamos uma edição:

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

    capa_do_jogo = request.form['capa_do_jogo']

    if capa_do_jogo == 'None':
        return redirect(url_for('index'))
    else:
        arquivo = request.files['arquivo']
        upload_path = app.config['UPLOAD_PATH']
        timestemp = time.time()
        deleta_arquivos_de_imagem(jogo.id)
        arquivo.save(f'{upload_path}/capa{jogo.id}-{timestemp}.jpg')
        return redirect(url_for('index'))

Observe que nesta linha: capa_do_jogo = request.form['capa_do_jogo'] pegamos o valor da variável capa_jogo que estamos passando no input do tipo hidden e após isto, fazemos o teste para saber se ela é ou não None(lembrando que caso seja, não existe imagem para aquele jogo).

Neste sentido, caso seja None, redirecionamos direto para a nossa index.html e caso não seja, fazemos a atualização daquela imagem.

Pode parecer muitos passos, mas fique tranquilo, faça passo a passo e qualquer dúvida é só falar.

Abaixo, linkei um vídeo com o resultado esperado:

Editando arquivo flask - Alura Flask 2

Espero ter ajudado. Abraços e bons estudos!