Django实战(18):提交订单

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

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

 

  1. class Order(models.Model):

  2. name = models.CharField(max_length=50)

  3. address = models.TextField()

  4. email = models.EmailField()


  5. class LineItem(models.Model):

  6. product = models.ForeignKey(Product)

  7. order = models.ForeignKey(Order)

  8. unit_price = models.DecimalField(max_digits=8,decimal_places=2)

  9. quantity = models.IntegerField()

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

 

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

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

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

 

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

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

 

 

  1. def create_order(request):

  2. form = OrderForm(request.POST orNone)

  3. if form.is_valid():

  4. form.save()

  5. form = OrderForm()


  6. t = get_template('depotapp/create_order.html')

  7. c = RequestContext(request,locals())

  8. return HttpResponse(t.render(c))

关于事务处理

 

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

 

  1. @transaction.autocommit     在 save() 或 delete() 时自动提交事务。

  2. @transaction.commit_on_success   当整个view成功后提交事务,否则回滚( TransactionMiddleware采用的就是这种机制)

  3. @transaction.commit_manually  需要手动调用commit或rollback。

 

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

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

 

  1. @transaction.commit_on_success

  2. def create_order(request):

  3. form = OrderForm(request.POST orNone)

  4. if form.is_valid():

  5. order = form.save()

  6. for item in request.session['cart'].items:

  7. item.order = order

  8. item.save()

  9. clean_cart(request)

  10. return store_view(request)


  11. t = get_template('depotapp/create_order.html')

  12. c = RequestContext(request,locals())

  13. return HttpResponse(t.render(c))


你可能感兴趣的:(Django实战(18):提交订单)