You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask购物车开发技术咨询:商品增删功能实现问题及多商品购物车构建方案

Hey there! Let's work through your Flask shopping cart challenges together. I'll cover adding/removing items, displaying the full cart, and even tweak your checkout code to make it more reliable.

1. Core Shopping Cart Logic (Using Flask Session)

For a simple shopping cart, Flask's session is perfect—it stores cart data per user without needing a database backend for the cart itself (we'll still use your database for orders). First, make sure you've set a SECRET_KEY in your app (required for session functionality):

app.secret_key = "your-secure-random-secret-key-here"  # Use a strong random key in production

1.1 Add Items to Cart

Create a route to handle adding products. This will either increment the quantity of an existing item or add a new one to the cart:

@app.route('/add-to-cart', methods=['POST'])
def add_to_cart():
    product_id = request.form.get('product_id')
    quantity = int(request.form.get('quantity', 1))  # Default to 1 if quantity isn't provided

    # Fetch existing cart from session, or initialize empty list
    cart = session.get('cart', [])

    # Check if the product is already in the cart
    existing_item = next((item for item in cart if item['id'] == product_id), None)
    if existing_item:
        existing_item['quantity'] += quantity
    else:
        # Replace this with your actual product lookup logic
        # Example: Fetch product details from your database
        product = get_product_by_id(product_id)
        if product:
            cart.append({
                'id': product_id,
                'name': product['name'],
                'price': product['price'],
                'quantity': quantity
            })

    # Update the session with the modified cart
    session['cart'] = cart
    return redirect('/cart')  # Redirect to cart page to show updates

1.2 Remove Items from Cart

Add routes to either remove an item entirely or decrease its quantity:

# Remove an item completely from the cart
@app.route('/remove-from-cart/<product_id>', methods=['POST'])
def remove_from_cart(product_id):
    cart = session.get('cart', [])
    # Filter out the item to remove
    updated_cart = [item for item in cart if item['id'] != product_id]
    session['cart'] = updated_cart
    return redirect('/cart')

# Decrease quantity of an item (remove if quantity hits 0)
@app.route('/decrease-quantity/<product_id>', methods=['POST'])
def decrease_quantity(product_id):
    cart = session.get('cart', [])
    for item in cart:
        if item['id'] == product_id:
            item['quantity'] -= 1
            if item['quantity'] <= 0:
                cart.remove(item)
            break
    session['cart'] = cart
    return redirect('/cart')
2. Display the Full Cart Page

Create a route to render the cart with all items, plus total cost:

@app.route('/cart')
def cart():
    cart = session.get('cart', [])
    # Calculate total cost of all items
    total = sum(item['price'] * item['quantity'] for item in cart)
    return render_template('cart.html', cart=cart, total=total)

Example cart.html Template

This will show all cart items, quantity controls, and checkout option:

<h1>Your Shopping Cart</h1>
{% with messages = get_flashed_messages() %}
  {% if messages %}
    {% for msg in messages %}
      <div class="alert">{{ msg }}</div>
    {% endfor %}
  {% endif %}
{% endwith %}

{% if cart %}
  <table>
    <tr>
      <th>Product</th>
      <th>Price</th>
      <th>Quantity</th>
      <th>Subtotal</th>
      <th>Actions</th>
    </tr>
    {% for item in cart %}
    <tr>
      <td>{{ item.name }}</td>
      <td>${{ "%.2f"|format(item.price) }}</td>
      <td>{{ item.quantity }}</td>
      <td>${{ "%.2f"|format(item.price * item.quantity) }}</td>
      <td>
        <form action="/decrease-quantity/{{ item.id }}" method="POST" style="display: inline;">
          <button type="submit">-</button>
        </form>
        <form action="/remove-from-cart/{{ item.id }}" method="POST" style="display: inline;">
          <button type="submit">Remove</button>
        </form>
      </td>
    </tr>
    {% endfor %}
  </table>
  <p class="total">Total: ${{ "%.2f"|format(total) }}</p>
  
  <form action="/checkout" method="POST">
    <label for="order_type">Order Type:</label>
    <select name="order_type" id="order_type">
      <option value="delivery">Delivery</option>
      <option value="pickup">Pickup</option>
    </select>
    <button type="submit">Proceed to Checkout</button>
  </form>
{% else %}
  <p>Your cart is empty! <a href="/products">Browse products</a></p>
{% endif %}
3. Refine Your Checkout Code

Your existing checkout logic works, but we can add error handling, user authentication checks, and cleaner database management:

from flask import flash

@app.route('/checkout', methods=['POST'])
def checkout():
    user_id = session.get('user_id')
    # Redirect unlogged-in users to login page
    if not user_id:
        flash('Please log in to checkout!')
        return redirect('/login')
    
    cart = session.get('cart', [])
    if not cart:
        flash('Your cart is empty!')
        return redirect('/cart')
    
    order_type = request.form.get('order_type')
    # Validate order type to prevent invalid data
    if order_type not in ['delivery', 'pickup']:
        flash('Invalid order type selected!')
        return redirect('/cart')
    
    try:
        # Use a context manager to auto-close the database connection
        with get_db() as conn:
            c = conn.cursor()
            for item in cart:
                c.execute('''
                    INSERT INTO orders (user_id, product_id, quantity, order_type, status)
                    VALUES (?, ?, ?, ?, ?)
                ''', (user_id, item['id'], item['quantity'], order_type, "Pending"))
            conn.commit()
        
        # Clear the cart after successful checkout
        session.pop('cart', None)
        flash('Your order has been placed successfully!')
        return redirect('/orders')
    except Exception as e:
        # Rollback on error and notify user
        conn.rollback()
        flash(f'Error placing order: {str(e)}')
        return redirect('/cart')

Key Notes

  • Make sure your get_db() function returns a database connection (example for SQLite):
    import sqlite3
    
    def get_db():
        conn = sqlite3.connect('your_database.db')
        conn.row_factory = sqlite3.Row  # Allows accessing columns by name
        return conn
    
  • Add flash message rendering to your base template to show user feedback (like success/error messages).

内容的提问来源于stack exchange,提问作者ghosty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 09:17:38