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

atualizacao do carrinho de compras

bom dia, sigo com duvidas sobre o carrinho de compras. nesta jogoteca eu distribui os jogos em categorias de acao e aventura

eu tenho estas rotas:

@app.route('/add_to_cart/int:id') def add_to_cart(id): if 'cart' not in session: session['cart'] = [] if id not in session['cart']: #isso aqui foi na tentativa de incluir mais itens porem so fica o primeiro item selecionado session['cart'].append(id) return redirect(url_for('cart'))

@app.route('/cart') def cart(): items = [acao.query.get(id) for id in session['cart']] items = [aventura.query.get(id) for id in session['cart']] total = sum(item.preco for item in items) return render_template('cart.html', cart=items, total=total)

porem somente o primeiro item que eu clico fica, quando eu clico nos outros nao há acrescimo de itens, permanece sempre o mesmo. como faco para adicionar mais itens no carrinho?

outra duvida, esses itens ficam armazenados na session, isso? nao no banco de dados. se for no banco de dados como que passa uma lista para o banco de dados? porque nos vimos um dicionario, correto? (os jogos estao armazenados em um dicionario no banco de dados, com varios topicos, como transecrever em lista? nao estou entendendo essa parte.

3 respostas

Olá, Patricia! Parece que você está fazendo um ótimo trabalho com o Flask!

Sobre a sua primeira dúvida, parece que o problema está na forma como você está buscando os itens para adicionar ao carrinho. Você está tentando buscar os itens de duas tabelas diferentes (acao e aventura) com o mesmo id, o que pode estar causando o problema. Se acao e aventura são duas tabelas diferentes, eles podem ter itens com o mesmo id, pois o id é único para cada tabela.

Uma solução seria armazenar não apenas o id do item, mas também o tipo de item (ação ou aventura). Assim, você poderia buscar o item correto na tabela correta. Por exemplo:

@app.route('/add_to_cart/<string:item_type>/<int:id>')
def add_to_cart(item_type, id):
    if 'cart' not in session:
        session['cart'] = []
    session['cart'].append({'type': item_type, 'id': id})
    return redirect(url_for('cart'))

@app.route('/cart')
def cart():
    items = []
    for item in session['cart']:
        if item['type'] == 'acao':
            items.append(acao.query.get(item['id']))
        elif item['type'] == 'aventura':
            items.append(aventura.query.get(item['id']))
    total = sum(item.preco for item in items)
    return render_template('cart.html', cart=items, total=total)

Quanto à sua segunda pergunta, sim, os itens do carrinho estão sendo armazenados na sessão, não no banco de dados. A sessão é uma maneira de armazenar informações específicas do usuário entre as solicitações de página. Quando um usuário fecha o navegador, a sessão geralmente termina.

Se você quiser armazenar os itens do carrinho no banco de dados, você precisaria criar uma nova tabela para armazená-los. Você poderia ter uma tabela Cart que tem uma relação muitos-para-muitos com a tabela Item (ou Acao e Aventura, se essas são suas tabelas de itens). Cada linha na tabela Cart representaria um item no carrinho, e você poderia adicionar e remover linhas para adicionar e remover itens do carrinho.

Espero ter ajudado e bons estudos!

oi Renan, bom dia. Ainda não estou conseguindo. eu fiz a rota como voce mencionou e esta dando o erro no terminal if item['type'] == 'acao': ~~~~^^^^^^^^ TypeError: 'int' object is not subscriptable

e tambem não acessa a pagina cart....com ajuda do chat eu fiz este codigo @app.route('/cart') def cart(): items = [] for item in session.get('cart', []): if isinstance(item, dict) and 'type' in item: if item['type'] == 'acao': items.append(Acao.query.get(item['id'])) elif item['type'] == 'aventura': items.append(Aventura.query.get(item['id'])) total = sum(item.preco for item in items) return render_template('cart.html', cart=items, total=total)

ela exibe o carrinho porem so o primeiro item, não esta adicionando mais itens. Por favor me ajude porque eu não tenho pra quem pedir ajuda e não estou conseguindo... 
o html esta assim
     {% if cart %}
            <ul class="list-group">
            {% for item in cart %}
              <li class="list-group-item">{{ item.nome }} - {{ item.preco }}  </li>
            {% endfor %}
            </ul>
            <p>Total: {{ total }}</p>
          {% else %}
            <p>Seu carrinho está vazio.</p>
          {% endif %}>
          
          a rota completa ficou assim

@app.route('/add_to_cart/string:item_type/int:id') def add_to_cart(item_type, id): if 'cart' not in session: session['cart'] = [] session['cart'].append({'type': item_type, 'id': id}) return redirect(url_for('cart'))

@app.route('/cart') def cart(): items = [] for item in session.get('cart', []): if isinstance(item, dict) and 'type' in item: if item['type'] == 'acao': items.append(Acao.query.get(item['id'])) elif item['type'] == 'aventura': items.append(Aventura.query.get(item['id'])) total = sum(item.preco for item in items) return render_template('cart.html', cart=items, total=total)

e no html dos das categorias está assim:
 <div class="card-header back-card">
                    <h4 class="text-center">{{ acao.nome }}</h4>
                    <p class="text-center">Preço R$: {{acao.preco }}</p>
                    <p ><a href="{{ url_for('add_to_cart', item_type='acao', id=acao.id) }}" class="btn btn-sm btn-light">Carrinho</a></p>
                  </div>

mas uma vez peço ajuda. grata

solução!

Olá novamente!

Em relação ao erro TypeError: 'int' object is not subscriptable, isso acontece quando você tenta acessar um índice ou chave em um objeto que não suporta essa operação. Parece que há algum item na sua lista de session['cart'] que não é um dicionário como esperado. O código que você adicionou para verificar se é um dicionário antes de acessar as chaves é uma boa abordagem para evitar esse tipo de erro.

Vamos tentar ajustar ainda mais o código para garantir que apenas itens válidos sejam processados:

@app.route('/cart')
def cart():
    items = []
    for item in session.get('cart', []):
        if isinstance(item, dict) and 'type' in item and 'id' in item:
            if item['type'] == 'acao':
                items.append(Acao.query.get(item['id']))
            elif item['type'] == 'aventura':
                items.append(Aventura.query.get(item['id']))
    total = sum(item.preco for item in items)
    return render_template('cart.html', cart=items, total=total)

Explicando o código acima:

session.get('cart', []): Garante que, se 'cart' não estiver presente na sessão, seja retornada uma lista vazia. isinstance(item, dict) and 'type' in item and 'id' in item: Verifica se 'item' é um dicionário e contém as chaves 'type' e 'id', evitando possíveis erros. Se as verificações passarem, o código adiciona o item ao carrinho. Para 'acao', utiliza a classe Acao do banco de dados; para 'aventura', utiliza a classe Aventura. Essas modificações visam garantir que apenas itens válidos e completos sejam processados, minimizando erros. Se tiver mais dúvidas ou algo não estiver claro, estou à disposição!

Agora, quanto ao problema de não adicionar mais itens ao carrinho, verifique se o link para adicionar ao carrinho está correto no seu HTML. Certifique-se de que o url_for está gerando a URL correta e que os parâmetros estão sendo passados corretamente.

<a href="{{ url_for('add_to_cart', item_type='acao', id=acao.id) }}" class="btn btn-sm btn-light">Carrinho</a>

Verifique se acao.id está retornando o valor esperado e se a rota está sendo chamada corretamente ao clicar no botão.

Se após essas verificações ainda houver problemas, por favor, me informe para que eu possa ajudar a identificar e resolver.