(转)Django ====> 实战学习篇九 在session中保存购物车
在session中保存购物车:
之前实现了产品目录的界面,用户看到合适的产品,就会加入购物车,对于购物车界面,需要考虑一下几点:
- 购物车应该显示:物品的清单,列出买方选中的产品;
- 购物车的清单有没有必要立即放入到数据库中,因为在用户结帐之前,这个单子都会变动,我们只是需要在用户的session中保存这些数据就行了;
购物车条目的显示分析:
- 在这个条目中,与产品目录中的信息差不多,但是我们没有必要重新统计一遍,可以直接使用产品目录中的信息。
- 除了产品目录中的信息,还需要添加的信息是产品的数量,这在产品目录信息中没有,另外考虑到有折扣信息等,需要添加一个单价属性,记录下来用户买到查品时候的价格。
设计的模型如下:/depotapp/models.py:
class LineItem(models.Model): product = models.ForeignKey() unit_price = models.DecimalField(max_digits=8, max_places=2) quantity = models.IntegerField()
购物车分析:
- 购物车相当于买方买的物品的容器,装有统计的信息,要体现出一些购物车“聪明”的功能;
- 当加入一个已经存在的物品条目时,不用另外加一个条目,而是合并到已存在的物品条目中,并显示出数量;
- 基于上边的多个条目,所以购物车也是一个模型类,但是考虑到购物车应用并不用记录到数据库中,所以是一个普通类,而不是继承自models的类;
设计的模型如下:/depotapp/views.py or models.py
class Cart(object): def __init__(self, *args, **kwargs): self.items = [] self.total_price = 0 def add_product(self,product): self.total_price += product.price for item in self.items: if item.product.id == product.id: item.quantity += 1 return self.items.append(LineItem(product=product, / unit_price=product.price,quantity=1))
URLconf view函数 模板的完成:
- url的映射关系添加到urls.py中:
(r'cart/view/', view_cart),
- 在view函数中定义视图函数view_cart:
购物车是保存在session中的,所以用request.session.get来获取 def view_cart(request): cart = request.session.get("cart", None) t = get_template("depotapp/view_cart.html") if not cart: cart = Cart() request.session['cart'] = cart c=RequestContext(request, locals()) return HttpResponse(t.render(c))
- 添加模板/depot/templates/depotapp/view_cart.html:
{% extends "base.html" %} {% block title %} 我的购物车{% endblock %} {% block pagename %} 我的购物车 {% endblock %} {% block content %} <div class="row"> <div class="span10"> <table class="condensed-table"> <thead> <tr> <th class="header">数量</th> <th class="yellow header">名称</th> <th class="blue header">单价</th> <th class="green header">小计</th> </tr> </thead> <tbody> {% for item in cart.items %} <tr> <th>{{item.quantity}}</th> <td>{{item.product.title}}</td> <td>{{item.unit_price}}</td> <td>{% widthratio item.quantity 1 item.unit_price %} </td> </tr> {% endfor %} <tr> <th></th> <td></td> <th>总计:</th> <th>{{cart.total_price}}</th> </tr> </tbody> </table> </div> <div class="span4"> <p><a class="btn primary span2" href="#">继续购物</a></a> </p> <p><a class="btn danger span2" href="#">清空购物车</a></p> <p><a class="btn success span2" href="#">结算</a> </p> </div> </div> {% endblock %}
因为django的设计理念是“业务逻辑层和表现逻辑层分开”,所以尽量在django模板中不建议执行过多代码,在小计的时候用了django模板的widthratio标签,该标签的原意是按比例计算宽度:根据当前值(this_value)和最大值(max_value)之间的比例,以及最大宽度(max_width)计算出当前的宽度(this_width),即{% widthratio this_value max_value max_width %} = max_width * this_value / max_value。但是如果我们设定max_value=1,就可以通过width ratio在Django模板中进行乘法计算了。同理还可以进行除法计算。总计价格的信息是通过Cart模型类实现的。
本篇文章都是转的文章,同时加入了关于django1.4版本的相关不同设置,完成这个实例的过程中,特别感谢原作者,原文地址:http://blog.csdn.net/thinkinside
如果session这个app没有打开的话,手动打开,并sync同步数据库,不过1.4版本以上的都是自动打开的,所以就不用手动的处理了,运行server,打开下边网址:http://localhost:8000/depotapp/cart/view/
只是一个购物车的界面,不能加入物品,也不能去掉商品,需要我们加入网页之间的联动。