The view flow at checkout.

115 views
Skip to first unread message

legutierr

unread,
Sep 29, 2011, 12:59:34 PM9/29/11
to django-shop
Hi all-

I have some questions about how the user flow works at the time of
checkout. In reading the documentation, it does not seem clear to me
the nature of the views implemented in django-shop, to what extent
they are reusable as-is, how to subclass them (if they are, as I
assume, class-based), and even what they are.

From an extensibility point of view, it seems clear from the
documentation how to extend a product, but not at all clear how to add
it to a shopping cart, whether there is an existing view that is to be
used, or whether one should

Another confusion I have is what to do to modify, or even use, the
check-out process. Where would a discount code be input? When would
cart.update() be called so as to apply that discount code using a cart
modifier?

Regards,

Eduardo

Tribaal

unread,
Sep 29, 2011, 4:15:13 PM9/29/11
to djang...@googlegroups.com
Thanks for your remarks - this is indeed lacking.

Any good soul to tackle this problem? I'm about to leave for my
honeymoon (yay!) for 3 weeks, so there will be no time for me in this
period.
If it can wait I'll try to hack a piece of doc when I'm back (I should
have *some* time then hopefully).

Cheers!

- Chris

Martin

unread,
Oct 6, 2011, 9:52:32 AM10/6/11
to djang...@googlegroups.com
Hey Eduardo,

I'm so sorry but I am swamped with work and can't help with enhanced docs in the next 2 weeks :(

You should dig yourself through the code in order to find your way along.
  • Start with urls.py (https://github.com/divio/django-shop/blob/master/shop/urls.py)
  • See, that /checkout/ uses CheckoutSelectionView
  • Go to that view (https://github.com/divio/django-shop/blob/master/shop/views/checkout.py)
  • You will learn that in the view's post method, when all forms are valid, this happens: return HttpResponseRedirect(reverse('checkout_shipping'))
  • Great, so back to urls.py ... we learn that 'checkout_shipping' is handled by ShippingBackendRedirectView
  • We learn that that view redirects to the shipping backend the user has chosen on the CheckoutSelectionView
  • Most probably that backend will be implemented by yourself. It will have one or more URLs that are handled by one or more views. 
  • Somewhere in your shipping backend you should call self.shop.add_shipping_costs (see here: https://github.com/divio/django-shop/blob/master/shop/shipping/api.py)
  • And you might want to call self.shop.finished(), which will redirect to 'checkout_payment'
  • Back at urls.py you will learn, that 'checkout_payment' is handled by PaymentBackendRedirectView (but at this point, you would have already guessed that anyways)
  • Again, that view just redirects to your own payment backend. Again it will have one or more URLs handled by one or more views.
  • You might want to call self.shop.confirm_payment (see https://github.com/divio/django-shop/blob/master/shop/payment/api.py)
  • And you might want to call self.shop.get_finished_url which will redirect to 'thank_you_for_your_order'
  • That one, finally, is handled by the ThankYouView which, sets the order to COMPLETED
One big pain point here is the CheckoutSeletionView. It cannot easily be replaced, so if you want to change behavior here, you need to place that URL somewhere before your other shop URLs so that the view will be handled by your own CheckoutSelectionView which might derive from the original one. For example you might only have one shipping backend, so you don't want to provide a form for shipping backend selection and you also don't want to redirect to your shipping backend because nothing really would happen there. So you could override the CheckoutSelectionView, make it use some other custom forms and redirect to your payment backend straight away. This would probably also be a good point to place another form for entering a promo code. I think, Order models can be replaced by custom ones via a setting, so you might want to create a custom order model that has a field for promo code. When the user does a POST to the CheckoutSelectionView you might want to save the entered promo code to the order and save the order.

You can also decide to not use self.shop.finish and self.shop.get_finish_url at all and let your backends redirect to totally new views that you can make up yourself. I like to inject a OrderOverviewView that shows the total price, tax, shipping costs and eventually occuring additional costs due to the chosen shipping backend (pay on delivery costs extra). This might also be a good place for you to show the real total price for users with promo codes. Only when the user clicks "Ok, I really want this shit", we get to the thank you view (again a custom one) and I make sure that the shop owner and the user receive emails.


Sorry for being rather vague. I admit that the docs are pretty useless at the moment. And I also believe that current workflow enforced by the CheckoutSelectionView and the shop APIs is not optimal. When Tribaal is back, I will discuss with him how we can make all this stuff easier. Its a real pain in the ass at the moment :(

Hope it somehow helps anyways. Just don't be afraid to dive into the code. It's quite well structured and readable. Much better than any docs we have at the moment.

Cheers,
Martin
Reply all
Reply to author
Forward
0 new messages