Django實戰(18):提交訂單


前面的內容已經基本上涵蓋了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關聯)。如下:

 

[python] view plain copy
  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視圖函數:

 

[html] view plain copy
  1. <aclass="btn success"href="{% url depotapp.views.create_order %}">結算</a>

兩 個界面就鏈接起來了。但是自動生成的訂單界面並沒有將session中的條目保存到數據庫,也沒有清空購物車,並且提交訂單后沒有返回到產品目錄界面,所 以還要對其進行修改。主要的修改在create_order視圖函數中進行。為了方便對比,將生成的原始視圖函數列出如下:

 

 

[python] view plain copy
  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)來實現,有三種修飾符可以選擇:

 

[plain] view plain copy
  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視圖函數如下:

 

[python] view plain copy
  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))

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM