大家好,欢迎来到IT知识分享网。
博客目录:
……
十四、Django+mysql(大堂点餐:需求分析和代码逻辑实现梳理、首页展示)
十五、基于Django+mysql的点餐系统设计-第十五篇(大堂点餐:登录)
十六、Django+mysql-第十六篇(大堂点餐:登录页面校验、登录中间件)
十七、基于Django+mysql的点餐系统设计-第十七篇(大堂点餐:购物车)
源码地址:https://github.com/hopeSuceess/testorder/tree/testorder_
本篇讲一下大堂点餐的购物车操作。试想一下,当顾客点了一份红烧肉+狮子头+饮料、红烧肉+番茄鸡蛋等套餐,店员应该清楚的记录顾客点餐的信息并进行存储,这些信息存储到哪呢?购物车应用而生。初始时,顾客点了一份红烧肉+狮子头+饮料,购物车会出现一份该套餐的信息。如果该顾客继续点红烧肉+狮子头+饮料,店员可以继续在餐品首页点击购买,也可以在购物中点击”+”号增加一份。另外,在购物车中也可以对套餐进行删减,点击”-“号即可。
”-“号虽然可以删减某一餐品的数量,但删减到一份就固定不变了。若要将该餐品彻底删掉,需要加一个删除按钮。如果要将购物车中的所有餐品都删除,那就应该加一个一键清空的功能。
上述需求概要分析了,那么现在就开始进行代码实现了。购物车说白了还是url控制器+MTV对数据增删改查的操作。“增”是基础,先看购物车中的餐品增加是怎么实现的。
说到餐品的增加,这次代码逻辑分析和以前不同,咱们现在反向来进行分析。看店员餐品首页,店员点击某一餐品,会触发增加的逻辑,然后将该餐品加到购物车中。那就看前端触发机制怎么实现。从前面几篇文章的编写咱们可以知道,餐品首页是前端代码通过将后端传过来的数据遍历后展示出来的,点击餐品就会在购物车中增加餐品的触发机制就应该写到这段遍历代码中。
<div class="col-md-8"> <!--标签页内容--> {% for key,category in categorylist %} <h5 style="padding-bottom: 9px;border-bottom:1px solid #eee;color: #BB3D00"><span class="glyphicon glyphicon-list" aria-hidden="true">{{ category.name }}: </h5> <div class="row shoplist"> {% for product in category.pids %} <div class="col-sm-6 col-md-3"> <div class="thumbnail"> <img src="{% static 'uploads/product' %}/{{ product.cover_pic }}" width="150" alt="..."> <div class="caption"> <h6>{{ product.name }}</h6> <div class="bn">¥<span class="price">{{ product.price }}</span>元</div> <a href="{% url 'web_cart_add' product.id %}" class="btn btn-warning btn-xs pull-right" role="button"><span class="glyphicon glyphicon-shopping-cart" aria-hidden="true"></span> 购买</a> </div> </div> </div> {% endfor %} </div> {% endfor %} </div>
看上面的前端代码,每个餐品都添加了购买的功能,店员如果点击购买会触发后端的添加函数 <a href=”{% url ‘web_cart_add’ product.id %}” class=”btn btn-warning btn-xs pull-right” role=”button”><span class=”glyphicon glyphicon-shopping-cart” aria-hidden=”true”></span> 购买</a>
从前端倒退的话,要在url路由控制器中添加路由了
# 为url路由添加请求前缀web/,凡是带此前缀的url地址必须登录后才能访问
path(“web/”, include([
path(”, index.webIndex, name=”web_index”), #前台大堂点餐首页
#购物车信息管理路由
path(‘cart/add/<str:pid>’, cart.add,name=”web_cart_add”), #购物车新增
path(‘delweb’, index.delweb, name=”web_delweb”), # 退出大堂点餐系统
]))
从购物车新增的路由中推断出要建一个cart.py,然后在cart.py中创建一个add函数来处理店员点击的餐品新增到购物车的需求。后端的add函数处理的逻辑很多,需要静下心来多梳理下逻辑关系。如果记不住可以多敲几遍代码,熟能生巧。看add函数的代码:
def add(request,pid): ''' 添加购物车操作 ''' #从session中获取当前店铺中所有菜品信息,并从中获取要放入购物车的菜品 product = request.session['productlist'][pid] product['num'] = 1 #初始化当前菜品的购买量 #尝试从session中获取名字为cartlist的购物车信息,若没有返回{} cartlist = request.session.get('cartlist',{}) #判断当前购物车中是否存在要放进购物车的菜品 if pid in cartlist: cartlist[pid]['num'] += product['num'] #增加购买量 else: cartlist[pid] = product #放进购物车 #将cartlist购物车信息放入到session中 request.session['cartlist'] = cartlist #print(cartlist) #跳转到点餐首页 return redirect(reverse('web_index'))
到此,一个完整的流程走完了,启动工程,访问http://127.0.0.1:8000/web/ ,正常跳转到了餐品首页。
上面的逻辑走通了,现在已经把选择的餐品放到购物车中了。但是购物车中的餐品数量没有展示出来、还需要实现对数量的增减。好,现在就实现这几个功能。购物车的餐品数量没有展示出来,怎么实现呢?哈哈,其实很简单,在前端代码中将餐品数量都出来就可以了。购物车中的数据都存放在名为cartlist的缓存中了,购物车的前端代码也是遍历cartlist,获取cartlist中每个餐品的数量就可以了。看templates/web/index.html中的代码实现:
{% for product in request.session.cartlist.values %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{product.name}}</td>
<td class=”num”><i onclick=”window.location=”” class=”btn btn-default btn-xs”> – </i>
<span>{{ product.num }}</span><i onclick=”window.location=”” class=”btn btn-default btn-xs”> + </i></td>
<td class=”price”>{{ product.price }}</td>
<td><a href=”” class=”btn btn-danger btn-xs” role=”button”>删除</a></td>
</tr>
{% endfor %}
餐品数量的展示是不是很简单,只需一段代码<td>{{product.name}}</td>搞定。这里注意下{{ forloop.counter }},这个变量的作用是给新增的每个餐品添加序号。
现在说一下对购物车中每一个餐品的增减,在web/urls.py中“新增购物车更改”的路由
# 为url路由添加请求前缀web/,凡是带此前缀的url地址必须登录后才能访问 path("web/", include([ ...... path('cart/change', cart.change, name="web_cart_change"), # 购物车更改 ...... ]))
路由定义好了,就到了view层的处理逻辑了。在web/views/cart.py中创建change函数,代码如下:
def change(request): ''' 更改购物车信息操作 ''' #尝试从session中获取名字为cartlist的购物车信息,若没有返回{} cartlist = request.session.get('cartlist', {}) pid = request.GET.get("pid",0) # 获取要修改的菜品id m = int(request.GET.get('num',1)) #要修改的数量 if m < 1: m = 1 cartlist[pid]['num'] = m #修改购物车中的数量 # 将cartlist购物车信息放入到session中 request.session['cartlist'] = cartlist # 跳转到点餐首页 return redirect(reverse('web_index'))
翻译下上面的代码:因为在add函数中定义过购物车的缓存信息cartlist,所以先获取cartlist。在前端获取菜品id,然后再从前端修改要修改的数量。
if m < 1: m=1 定义了数量最少是1,当数量等于1时,就不能再删减了。菜品id有了,修改后的数量有了,可以更改购物车中该餐品的数量了:cartlist[pid][‘num’]=m。将修改后的cartlist重新放到缓存中,最后将数据返回到前端餐品页。
后端的处理逻辑最终会在前端展现,现在说下前端的逻辑,在购物车中进行餐品的增减,代码如下:
{% for product in request.session.cartlist.values %}
<tr><br> ……
<td class=”num”><i onclick=”window.location='{% url ‘web_cart_change’ %}?pid={{ product.id }}&num={{ product.num|add:-1 }}'” class=”btn btn-default btn-xs”> – </i>
<span>{{ product.num }}</span><i onclick=”window.location='{% url ‘web_cart_change’ %}?pid={{ product.id }}&num={{ product.num|add:1 }}'” class=”btn btn-default btn-xs”> + </i></td><br> ……
</tr>
{% endfor %}
看上面的代码,触发增/减的点击事件时,会调用后端的change函数进行逻辑处理,在将处理信息发送到后端时,会带上缓存中存储的产品id和增/减后的数量。经过后端change函数的逻辑处理后,将处理结果再反转到前端,餐品的数量就变化了。
好了,现在启动工程,访问大堂点餐餐品首页,对购物车中的餐品进行增/减,功能正常。
购物车的新增、餐品增/减功能都实现了,现在实现购物车的清空和某一餐品的清除功能。先看购物车清空,这个功能非常简单。就是将购物车缓存信息删除就可以了,这个功能很简单,这里只贴一下view层的处理逻辑,web/views/cart.py中clear函数代码如下:
def clear(request):
del request.session[‘cartlist’]
<br> return redirect(reverse(‘web_index’))
哈哈,代码是不是很简单。再看一下购物车中某一餐品信息的删除,其实某一餐品信息只是多了一个餐品id。前端点击删除时给后端传一个餐品id号,然后后端只针对购物车缓存中该餐品id号的信息删除就可以了。
在前端购物车遍历的代码中添加商品删除的代码,如下:
{% for product in request.session.cartlist.values %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{product.name}}</td>
……
<td><a href=”{% url ‘web_cart_delete’ product.id %}” class=”btn btn-danger btn-xs” role=”button”>删除</a></td>
</tr><br> {% endfor %}
前端点击删除,先去找路由,然后路由引导到后端去处理。逻辑很简单,这里说下后端的处理情况,在web/views/cart.py中新增delete函数。先获取购物车缓存,然后匹配前端传过来的菜品id,在购物车缓存中删除该餐品,然后将做过变动的购物车缓存重新定义后放到cartlist中,最后将结果反馈到餐品首页。该功能逻辑的代码如下:
def delete(request,pid): cartlist = request.session.get('cartlist', {}) del cartlist[pid] request.session['cartlist'] = cartlist return redirect(reverse('web_index'))
好了,试下清空和删除的功能,功能正常。
购物车的章节到这里就告一段落了,下一章节讲下单操作。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/108739.html