不能为多个项目更新购物车,对于单个项目可以正常工作,否则仅更新第一个项目

2024-06-01 02:12:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图通过更改下拉列表中的数字来更新购物车中的产品数量。如果购物车有两个或多个项目,则只有第一个项目有效,其他项目的数量即使在下拉列表中更改后也不会更改。我从HTML表单中获取相应的“productid”和“size”,并尝试使用这三个值操作sqlite数据库。 (想知道是否有办法仅从下拉列表中获取其数量正在更改的项目的“数量”值?) 由于request.form.get()只返回第一个值,所以我考虑使用request.form.getlist()。但接下来我必须弄清楚如何将数组(例如qtychanged[]、productid[]和size[]输入Cart1表中。(将HTML文件作为模板附加)

 <!DOCTYPE html>

 <html lang="en">

 <head>

    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- documentation at http://getbootstrap.com/docs/4.1/, alternative themes at https://bootswatch.com/ -->
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet">


    <!-- https://favicon.io/emoji-favicons/money-mouth-face/ -->
    <!--<link href="/static/favicon.ico" rel="icon">-->

    <link href="/static/styles.css" rel="stylesheet">

    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>

    <script type="text/javascript" src="/path/to/jquery.js"></script>
    <script type="text/javascript" src="/path/to/jquery.jcarousel.js"> 
</script>

</head>
<body>


<body>


    <form action="/updatecart" method="post">

     {% for item in shoppingcart %}

  <div class="Tcard">
    <div class='container2'>
      <p style="text-align:center">{{ item. name }}</p>
      <p class = "image"><img src= "{{ url_for('static', filename = item.image) }}" alt="Top 1" width ="100px" height = "100px"></p>
      <p class="price">Price: ${{ item.price }}</p>

      <label for="qty">Qty:</label>

          <select name = "qtydropdown" class = "qtydropdown" id = "mySelect"  onchange='this.form.submit()'>
               <option value="{{ item.qty }}">{{ item.qty }}</option>
                <option value="0">0 - Remove</option>
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
                <option value="4">4</option>
                <option value="5">5</option>
                <option value="6">6</option>
                <option value="7">7</option>
                <option value="8">8</option>
                <option value="9">9</option>
                <option value="10">10</option>
            </select>

            <noscript><input type="submit" value="Submit"></noscript>

          <p class = "fontgrp">Size: {{ item.size }}</p>
          <p class = "fontgrp"><b>Total Cost: {{ item.total | usd }}</b></p>
      </div>
    </div>

 <div>
    <input id="productid" name="productid" type="hidden" value="{{ item.productid }}">
    <input id="size" name="size" type="hidden" value="{{ item.size }}">
 </div>

 {% endfor %}

 <div>
<input class = "btn btn-primary" value = "Grand Total: {{ grandtotal | usd }}">
</div>
<br>
<div>
<a href="/checkout" class="btn btn-primary" role="button" aria-pressed="true">Checkout</a>
  <!--<input form action = "/checkout" class="btn btn-primary" type="submit" value="Checkout">-->
  </div>
</form>
</body>
</html>

@app.route("/updatecart", methods = [ "POST"])    
def updatecart():

if request.method == "POST":
            
            shoppingcart = db.execute("select * from cart1") 
            
    #getting the qty from the html dropdown         
            qtychanged = request.form.get("qtydropdown")
        
     # productid corresponding to the qty       
            productid = request.form.get("productid")
            
      # size corresponding to the qty  
            size = request.form.get("size")
           
        
            for rows in shoppingcart:
                if int(qtychanged) == 0:
                            
                            
                            shoppingcart = db.execute("update cart1 set qty = :qty where productid = :productid and size = :size",
                            productid = productid,
                            size = size,
                            qty = qtychanged)
                            
                            
                            shoppingcart = db.execute("delete from cart1 where qty = :qty", qty = qtychanged)
                            
                            shoppingcart = db.execute("select * from cart1")
                            
                            if not shoppingcart:
                                return apology("Cart is empty")
                         
                               
                if len(shoppingcart)!=0:
                                       
                            shoppingcart = db.execute("select * from cart1 where productid = :productid and size = :size",
                            productid = productid,
                            size = size)
                            
                            
                            shoppingcart = db.execute("update cart1 set qty = :qty where productid = :productid and size = :size",
                            qty = qtychanged,
                            productid = productid,
                            size = size)
                     
                            shoppingcart = db.execute("select productid, name, size, qty, price, image, (qty * price) as total from cart1") 
                            if not shoppingcart:
                                return apology("Cart is empty")
                                
                            grandtotal = 0
                            
                            for row in shoppingcart:
                             
                                total = row["qty"] * float(row["price"])
                       
                        
                                grandtotal = grandtotal + total
                                return render_template("testcartlayout.html", shoppingcart = shoppingcart, total = total, grandtotal = grandtotal)  
            

Tags: divformexecutedbsizevaluejsscript
1条回答
网友
1楼 · 发布于 2024-06-01 02:12:59

假设问题中的HTML工作正常,那么可以对Python代码进行一些改进,以确保它产生您想要的结果,或者至少提供一些指针

  • 不需要SELECT所有行并在其上循环。使用SQL,您通常可以在一条语句中对所需的所有行进行操作
  • 要确定购物车是否为空,使用SELECT COUNT(1) FROM cart1检索行数比检索所有行更有效,可以调用len
  • DELETE的情况下,如果productidsize唯一地标识一行,那么delete it immediately using these criteria, there is no need to do an 首先更新`
  • 如果删除了一行,则不需要进行进一步的更新,因此DELETEUPDATE部分应位于if/else
  • grandtotal可以在数据库中计算:SELECT SUM (qty * price) FROM cart1-无需SELECT和循环
  • total始终是为选择中的最后一行计算的total:这似乎不是很有用(如果我们在数据库中计算grandtotal,它就不会被计算)

下面的函数显示了如何改进现有方法。请注意:

  • 我不知道你烧瓶设置的细节,所以这只是一个正常的功能;类似render_templateapology的烧瓶已被移除
  • 我不知道db到底是什么:您可能需要调整查询结果的处理
def updatecart(qtychanged, productid, size):

    # SELECT COUNT to get the number of rows in the table
    # without retrieving all of them.
    result = db.execute("select count(1) from cart1")
    shoppingcart = result.fetchone()[0]
    # If the cart is empty there is no point trying to do anything
    if not shoppingcart:
        return "Cart is empty"

    if int(qtychanged) == 0:
        # Delete unwanted product from the cart.
        # Assuming productid and size uniquely identify an
        # item in the cart, just delete no need to update
        db.execute(
            "delete from cart1 where productid = :productid and size = :size",
            productid=productid,
            size=size,
        )
        # Apologise if the cart is empty
        result = db.execute("select count(1) from cart1")
        shoppingcart = result.fetchone()[0]
        if not shoppingcart:
            return "Cart is empty"
    else:
        # We're not deleting, so let's update.
        db.execute(
            "update cart1 set qty = :qty where productid = :productid and size = :size",
            qty=qtychanged,
            productid=productid,
            size=size,
        )
    shoppingcart = db.execute(
        "select productid, name, size, qty, price, image, (qty * price) as total from cart1"
    )

    # Declare total to avoid error in return
    # In the original code, total would be the total computed
    # for the last row in the cart, which doesn't seem useful.
    total = 0

    # Compute the total price
    res = db.execute("""SELECT SUM(qty * price) FROM cart1""")
    grandtotal = res.fetchone()[0]

    return shoppingcart, total, grandtotal

我编写了一些代码来测试这个函数:您可以通过将函数粘贴到一个文件中来运行它,将下面的代码粘贴到函数代码之后,然后调用python myfile——如果需要,您可以使用它进行实验。唯一的外部依赖项是sqlalchemy,我用它来模拟db

if __name__ == "__main__":
    import dqlalchemy as sa
    engine = sa.create_engine("sqlite://", echo=True)
    with engine.connect() as db:
        db.execute(
            """CREATE TABLE cart1 (
          productid INTEGER,
          name TEXT,
          size TEXT,
          qty INTEGER,
          price INTEGER,
          image TEXT
        )"""
        )
        ins = """INSERT INTO cart1
                 (productid, name, size, qty, price, image)
                 VALUES (?, ?, ?, ?, ?, ?)"""
        data = [
            (1, "Hat", "L", 1, 10, ""),
            (2, "Coat", "M", 5, 100, ""),
            (3, "Shirt", "M", 3, 20, ""),
        ]
        # Test 1: empty cart returns message
        db.execute(ins, data[0])
        res = updatecart(0, 1, "L")
        assert res == "Cart is empty", f"Expected empty message got {res}"
        # Reset the database
        db.execute("""DELETE FROM cart1""")
        # Test 2: update a row
        db.execute(ins, *data)
        # Buy two more hats
        resultobj, total, grandtotal = updatecart(3, 1, "L")
        rows = resultobj.fetchall()
        assert len(rows) == 3, f"Expected 3 got {len(rows)}"
        assert grandtotal == 590, f"Expected 590 got {grandtotal}"
        # Reset the database
        db.execute("""DELETE FROM cart1""")
        # Test 3: delete a row
        db.execute(ins, *data)
        # Remove the shirts
        resultobj, total, grandtotal = updatecart(0, 3, "M")
        rows = resultobj.fetchall()
        assert len(rows) == 2, f"Expected 2 got {len(rows)}"
        assert grandtotal == 510, f"Expected 510 got {grandtotal}"

相关问题 更多 >