前面的内容已经基本上涵盖了Django开发的主要方面,我们从需求和界面设计出发,创建模型修改模型,并通过scaffold作为开发的起点;在scaffold的基础上重新定制模板,并且通过Model类和Form类对用户输入的数据进行校验。我们也涉及到了单元测试。为了提高开发用户界面的效率,更好地实现模板,我们还讨论了对静态资源(css,js,image等)的管理,并通过模板继承的方式实现了整个站点的统一布局。作为web应用必不可少的部分,我们还演示了如何使用会话(session)。最后,我们还在这些基础上增加了RESTful web service将jquery集成到Django,并实现了ajax

有了这些基础,可以应付Django开发中的绝大多数问题。

下面我们继续实现depot购物车的web应用。本节要实现提交订单功能。现在买方已经可以挑选需要的产品放入购物车,但是还不能进行购买。我们希望实现这样的功能:

买方点击”结算“按钮,然后输入姓名、地址和email信息,就向卖方发出了一张订单,该订单包含上述买方信息和其选购的所有条目。首先还是实现Model类。我们要增加一个订单类(Order),并修改原来的条目类(LineItem),增加到Order的外键(即LineItem到Order的many-to-one关联)。如下:

    class Order(models.Model):
name = models.CharField(max_length=)
address = models.TextField()
email = models.EmailField()
class LineItem(models.Model):
product = models.ForeignKey(Product)
order = models.ForeignKey(Order)
unit_price = models.DecimalField(max_digits=,decimal_places=)
quantity = models.IntegerField()

要注意,因为LineItem引用了Order,所以在定义模型类的顺序上要将Order放在前面。

前面介绍过修改模型类之后应该如何处理,这里就不再重复了。

然后祭出scaffold,快速生成一系列”丑陋“的界面。该工具还不够成熟,在生成之前,一定要备份depotapp/urls.py 、views.py 和 forms.py,之后手工合并,切记!

之后将产品目录界面(depot/templates/depotapp/store.html)中的”结算“标签的链接改为映射到生成的create_order视图函数:

    <aclass="btn success"href="{% url depotapp.views.create_order %}">结算</a>

两 个界面就链接起来了。但是自动生成的订单界面并没有将session中的条目保存到数据库,也没有清空购物车,并且提交订单后没有返回到产品目录界面,所 以还要对其进行修改。主要的修改在create_order视图函数中进行。为了方便对比,将生成的原始视图函数列出如下:

    def create_order(request):
form = OrderForm(request.POST orNone)
if form.is_valid():
form.save()
form = OrderForm()
t = get_template('depotapp/create_order.html')
c = RequestContext(request,locals())
return HttpResponse(t.render(c))

关于事务处理

”保存订单“和”保存订单条目“应该形成一个事务。Django的事务处理可以通过middleware自动添加,也可以手工添加。手工添加的方式更加灵活,通过在view函数前增加修饰符(decorator)来实现,有三种修饰符可以选择:

    @transaction.autocommit     在 save() 或 delete() 时自动提交事务。
@transaction.commit_on_success 当整个view成功后提交事务,否则回滚( TransactionMiddleware采用的就是这种机制)
@transaction.commit_manually 需要手动调用commit或rollback。

我们暂时不想使用middleware的方式,所以用@transaction.commit_on_success来实现事务管理。这需要引用transaction模块:from django.db import transaction

最终修改的create_order视图函数如下:

    @transaction.commit_on_success
def create_order(request):
form = OrderForm(request.POST orNone)
if form.is_valid():
order = form.save()
for item in request.session['cart'].items:
item.order = order
item.save()
clean_cart(request)
return store_view(request)
t = get_template('depotapp/create_order.html')
c = RequestContext(request,locals())
return HttpResponse(t.render(c))

Django实战(18):提交订单的更多相关文章

  1. DTcms手机版使用余额支付 提示信息跳转到PC版的错误。以及提交订单不打开新页面

    手机版使用余额支付 提示信息跳转到PC版的错误 引起错误的原因是中间需要提交到DTcms.Web\api\payment\balance\index.aspx去处理 导致BasePage.cs中的li ...

  2. 消息队列第二篇:MessageQueue实战(课程订单)

    上一篇:消息队列介绍 本篇一开始就上代码,主要演练MessageQueue的实际应用.用户提交订单(消息发送),系统将订单发送到订单队列(Order Queue)中:订单管理系统(消息接收)端,监听消 ...

  3. [实战]MVC5+EF6+MySql企业网盘实战(18)——文件上传,下载,修改

    写在前面 经过一段时间的秀秀改改,终于把文件上传下载,修改文件夹文件名称的功能实现了. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企 ...

  4. Django之Ajax提交

    Ajax 提交数据,页面不刷新 Ajax要引入jQuery Django之Ajax提交 Js实现页面的跳转: location.href = "/url/" $ajax({ url ...

  5. 从零开始部署Django生产环境(适用:《跟老齐学Python Django实战》)

    <跟老齐学Python Django实战>作为市面上少有的Django通俗实战书籍,给了我学习Django很大的帮助.作为一名新入门的菜鸟,全书我重复练习了至少三遍,每次都有新的收获. 前 ...

  6. 编写Java程序,模拟网上商城购物,当用户选好物品提交订单时,每笔订单会自动生成一个唯一的订单编号。

    查看本章节 查看作业目录 需求说明: 模拟网上商城购物,当用户选好物品提交订单时,每笔订单会自动生成一个唯一的订单编号.而部分电子商务网站在数据高峰期时,一毫秒可能需要处理近千笔的订单 现在简单模拟 ...

  7. 18、Django实战第18天:课程机构收藏功能

    这里点击"收藏"也是ajax异步操作,我在operation.model.py中创建了一个用户收藏表,其中fav_id字段,如果我们收藏的是课程,那就是课程id,如果收藏的是课程机 ...

  8. django实战商城项目注册业务实现

    设计到的前端知识 项目的前端页面使用vue来实现局部刷新,通过数据的双向绑定实现与用户的交互,下面来看一下需求,在用户输入内容后,前端需要做一些简单的规则校验,我们希望在在用户输入后能够实时检测,如果 ...

  9. Django实战(一)-----用户登录与注册系统6(session会话、注册视图)

    因为因特网HTTP协议的特性,每一次来自于用户浏览器的请求(request)都是无状态的.独立的. 通俗地说,就是无法保存用户状态,后台服务器根本就不知道当前请求和以前及以后请求是否来自同一用户.对于 ...

随机推荐

  1. 2 Kafka Broker

    Log的读写.删除流程---日志管理器(log manager)负责创建日志.获取日志.清理日志.所有的日志读写操作都交给具体的日志实例来完成. KafkaServer启动的时候,初始化三个类: Lo ...

  2. 基本UDP套接字编程

    概述 使用TCP编写的应用程序和使用UDP编写的应用程序之间存在一些本质差异,其原因在于这两个传输层之间的差别:UDP是无连接不可靠的数据报协议,非常不同于TCP提供的面向连接的可靠字节流.然而相比T ...

  3. ABOUT ME/OI回忆录

    \(ABOUT\ ME/OI回忆录\) 博主是一个退役的老菜鸡啦,学\(OI\)两年没搞过什么很厉害的东西,也没有做过很多题目,但是还是挺喜欢\(OI\)的. 在退役之后可能不会经常上博客园了,估计也 ...

  4. wait&waitpid状态值

    [wait&waitpid状态值] 1.  python 中 os.system 的返回值的format与wait的返回值status一致: On Unix, the return value ...

  5. Grep学习笔记

    Grep(Global search Regular Expression and Print out the line)是一种强大的文本搜索工具. 1. 正则表达式的基本组成部分 正则表达式 描述 ...

  6. HDU 4521 小明系列问题——小明序列 (线段树 单点更新)

    题目连接 Problem Description 大家都知道小明最喜欢研究跟序列有关的问题了,可是也就因为这样,小明几乎已经玩遍各种序列问题了.可怜的小明苦苦地在各大网站上寻找着新的序列问题,可是找来 ...

  7. POJ 1128 Frame Stacking (拓扑排序)

    题目链接 Description Consider the following 5 picture frames placed on an 9 x 8 array. ........ ........ ...

  8. 【译】第七篇 Integration Services:中级工作流管理

    本篇文章是Integration Services系列的第七篇,详细内容请参考原文. 简介在上一篇文章,我们创建了一个新的SSIS包,学习了SSIS中的脚本任务和优先约束,并检查包的MaxConcur ...

  9. Vue学习看这篇就够

    Vue -渐进式JavaScript框架 介绍 vue 中文网 vue github Vue.js 是一套构建用户界面(UI)的渐进式JavaScript框架 库和框架的区别 我们所说的前端框架与库的 ...

  10. APScheduler API -- apscheduler.schedulers.base

    apscheduler.schedulers.base API class apscheduler.schedulers.base.BaseScheduler(gconfig={}, **option ...