Developing ecommerce platform with Django Oscar

Modern technologies has changed the way how we buy and sell in the Internet nowadays. Thus, we also constantly evolve the way how we build projects to sell and buy goods using our technologies of choice - Python and Django. Ease of customization and flexibility made Oscar application of my choice for building custom ecommerce platforms on top of Django, allowing to satisfy client requirements without necessity of implementing solution from scratch, since Oscar have ready-made applications for basket, checkout, shipping etc, available for the further tweak and refinement.

I’ve been using and contributing to Django Oscar since 2015, designed and supported various ecommerce projects in different fields (food, accessories, shoes) and sizes during this time. In this talk I’m going to share some of the experience and conclusions about building complex ecommerce platform using Django, and eventually, Django Oscar.

I will go through the next topics:

  • architecture approaches (synchronous app vs SPA);
  • frontend (VueJS, React etc);
  • API (Django REST Framework and Oscar-API);
  • payment method integration;
  • multiple currencies, exchange rate and conversion;
  • custom pricing policies (sale price, wholesale prices);
  • single-page checkout;
  • substandard discounting systems (buyers club, bonus points system);
  • user roles and permissions (users, admins, partners) and data management;
  • Oscar pros and cons (when to use and when not to use).

This session was classified suitable for expert domain / expert python by the speaker.

Transcript (auto)

Auto-generated from the recording utilizing Open-Source AI. Speaker labels (Speaker 1, Speaker 2) reflect diarization, not identity. Timestamps refer to the recording.

Speaker 1 [00:03]

Okay, let's go. Okay, hello everyone. I'm Alexander Grigayevsky. I am a software engineer from Ukraine. I'm running a small agency, Metaclass. We're doing customer commerce development on top of Python 3 Django. And obviously Django Oscar. I started to write Python code in 2009. and Django Code from 2011. So I first made a contribution to Django Oscar in 2015 and in 2016 I became a core contributor. So what is Django Oscar? Django Oscar is pretty much a stand-alone Django application which has all commerce core functionality in the inside for the basket checkout flow shipping methods taxation analytics complete this board for products management products and order management and also it has like unprecedented level of extraction and customizability also it has discounting system inventory stock level alerts and identification is special. Okay, so, what is this, how the customization is powered? So, instead of making a direct impasse of classes and models, you have a get model utility, which is, which tries to load your model with this, from the specified application. And if it's model is custom one, it will load it. Otherwise, it will fall back to the original OSCQR model or class. You can even customize the way how it loads it by providing a setting. If you need to customize entire application like basket or checkout, you can use OSCQR for app management command and it will copy from the OSCQR package views, models and all modules you can later on edit them. Okay, so let's assume you decided to use OSCQR and nowadays how you can design the project architecture. Obviously we're talking not about some simple generic issue but something rather complex. Okay, you can just take the OSCQR and implement classic Django application. You can also implement single-page application or progress web application, or you can implement hybrid application, which is a mix of templates and some reactive front-end. You can read more about hybrid application approach in the article of America Augustine, making React and Django to play well together. So we should use it, actually, some other approaches, rather than just customizing the views and templates, if it's very easy. I mean, in terms of performance, I believe that single-page application has the biggest power, because you do not need to reload the pages, and you can just fetch data from the API. But if you want to implement, there is no boilerplate for the single-page application on top of the OSCAR, so you would basically need to implement it by yourself using React, Redux, Vue, VX, or I mean, IDA, or. And it could take something around, like, three months. So, but I believe the most compromised solution is to use, to implement hybrid. And, yeah, let's see. I mean, otherwise, we can see that for the basket management, Oscar uses firm sets. And it's only line firm sets. Also, there is a basket line inside this firm set. Yeah, it pretty much has a lot of code. And if you need to customize something, for example, availability, validation, or so on, you will need to dynamically load this form and rewrite the message in the form. We personally use hybrid approach in our projects our projects because it's a compromise of performance and development time. So you could use for that obviously something like React or Vue. We use mostly Vue because it's very easy to start with. And the simplest application is this. You can later on implement products, load from the API, and so on. Vue is also powerful, it has components, mixins, custom derivatives, plugins, filters, and so on. React has, I suppose, more power under the hood, but if you want to develop fast, I would recommend you view. Okay, so regarding the API. There is already existing application called Django Oscar API. It's a bridge between the Oscar core functionality and Django REST framework. So it has all necessary functionality in In the inside, you do not need to implement it from scratch. So it has basket management, checkout, order and order line details, user address management, login, product list, product pricing, and product availability. So basically it's enough to start with. We personally have some custom checkout flows, so sometimes we implement API from scratch. Okay, so basically nowadays we are not limited how to build a project either in Django or somehow else. But I believe that hybrid approach has a lot of advantages also in the UX. So let's see on the demo. It's a standard checkout flow of the Oscar. You go to the catalog, add the item to the basket, you manage your shipping addresses, and you can basically edit it. You can ship to this address. And finally, select the payment method, preview the whole checkout flow, and submit an order. You can see, for example, how the basket management could look like with a reactive front-end. So let's just skip it. The single page checkout. Single page checkout is a page where you have everything on basically one page. It has a shipping address management and selection, payment method selection, and everything is the one place which is basically if you show it to your clients they will be delighted because conversion is probably better on the single page account your customer do not need to leave the page and it's pretty much sleek and i'm not sure how you would implement this within the the classic Django application, because there is a lot of Frontend stuff here. If you're probably not convinced yet, I can show you catalog filters. So you have a product catalog, you select some criteria, and the Frontend fetches new products list from the API and just updates the list and you do not need to reload it on and on from the server. Okay also you probably there is good use case it's a shipping policy in a way similar to Shopify where you define fixed pricing and wait-based pricing. So this is also built on top of the Janko Oscar but it's heavily customized all right let's carry on so one of the most popular requests from the clients is to build multi-vendor marketplace by By default Django Oscar is a single vendor shop, so that means that we assume that all products are supplied by one supplier. But what about if you have a marketplace and you need to have products from multiple suppliers? You will need to implement subbasket and suborder models, which would be nested from the order. So basically it's not quite an easy job, but let's see a step by step. So firstly, you will need to alter your models and implement nested models for the basket and from the order. That will mean that subbasket is a separate basket with all products supplied by this particular supplier, only this one. And so each subbasket will be supplied by some unique partner. The same applies to the orders, like order will have nested orders and every suborder will be a mirror of the subbasket. Then you'll need to edit the original basket model. It has the add product method and basically you will need to propagate the addition of the product to the print model, also to the subbasket. And the last one, you'll need to edit order creator, which is in the order utils, and you'll need to inject some logic into the create order model. It has already a functionality to create order model. You will just need to create suborder containing the products of the specific vendor. Okay, let's see. So, of course, we will need to have a payment in the checkout flow and draw some ready-made community packages, which are more or less up-to-date. Okay, Django Oscar Data Cache, Oscar Paypal, Oscar DocData, and Oscar DN. If you have a standard eShop, it's pretty much easy to decide what to use, but in the marketplaces where you can't hold the money and you need to somehow charge your customer and split the payments, the best would be to use Stripe supercharges and transfers. It has a limitation, but if it works for you, it would be the best solution. To implement charges, you charge your customer, you immediately break this payment into the parts, and you make a payout for the suppliers. There is a standard design of implementing payment gateways in the OSCAR. There is a facade. Facade is a bridge between OSCAR and the gateway model. And gateway is a upset model which has the basically payment logic we can just skip it and implement good way so this is example how get we looks for their people bit low package so you can implement something for the stripe this also Stripe, Django Oscar Stripe, but it's only a skeleton, doesn't have any logic. We used to implement integration on a lot of our projects, so I mean there is a very convenient API in the Stripe, so it's a Stripe JavaScript SDK and Stripe wrapper for the Python. But where to put it into the checkout flow? There's the auto placement mixin. You can inherit it and inject the integration into the handle payment method. So if you implement API, you can take your checkout serializer and inherit the order placement mixin again and call the placeOrder method. Why placeOrder? Because it has also nested logic which creates model instances and so on and you just need to override handlePayment which has specifically payment processing. Okay, it's typically that you could also have another use case if you have a supplier in the separate countries, for example, France, Switzerland, Belgium, and you have prices in the different currencies. Oscar is not aware of the currency, I mean there is only a char field of the currency, but it's only for indication. So you can integrate ready-made Django application, Django money, Django currencies and Django money rates. So JunkoMoney has a money field and currency field. JunkoCurrencies has a currency model and it has already a factor field, which means a difference of the given currency and the base currency. But if you need to have some base currencies, for example, like Swiss francs, euro and dollars, it will not work, maybe. Also, JunkoMoney rates is pretty much suitable so it should all work as well but there is a one limitation here Oscar validates the currents that it enforces all products have the same currency when you try to edit so you will get the validation error and you will need to basically write an add product method in the model. Alright, but let's see some tricky cases that you may see. So, OscarHell is already under the hood of a good and And powerful discounting system, which has like four parts, is condition, conditional offer, range, and benefit. Condition is condition for the discount. Offer is basically the model which unites all of this. Range means the product range which this discount will be applicable for. and the benefit is what you will get from this deal. The benefits could be fixed price and percentage discounts and also you can get a discount for shipping as well. But for example if you need to sell something within the discounted pricing like today, and you don't want to provide vouchers and so on, because OSCQR has already great support for vouchers. You can give a voucher code to your customers, and they will get the discount. You can implement additional model. It could be called as a sale price, which will have a relation one-to-one with the stock record. It will have a sales price, which could be called as a price exclusive tax, and validation dates. Because the deal will be limited in time, right? um okay so um how to inject this in the oscar um you can override the default pricing strategy which is basically the um the class which decides on pricing availability and so on um you need to override pricing policy and basically here you see that we try to take a save price from the SOC record and if it exists we just apply it and I mean here we determine the pricing for the product throughout the OSCAR. It doesn't matter where you would see the product on the templates on the admin everywhere this method will be called. All right, another case is wholesale pricing. It's applicable for the wholesale e-commerce projects, which means that the more you buy, the less the smaller price you will have. So it encourages, for example, in the B2B platforms, It encourages the customers to buy more and to, obviously, vendors sell more as well. So there's already a solution, pretty much very suitable and great, by Vladimir Balshkov. He proposed to introduce price for quantity model. And we need these changes to indicate what price you will have for a given quantity. So you define your quantity in the quantity field and price in the price field accordingly. So, later in the partner pricing strategy, we will look in this model entries and we will fetch necessary pricing. Okay, let's see how these commands are applied. But there is an applicator class in the offer application, which has a site offers basket, user, and session. And you see that the user offers and session offers are empty and not implemented. But let's add something. So there is also a case for cumulative discounts. when you buy more and more and when you reach some limit of purchases, for example, 2,000 euro that year, you is granted some kind of membership and later you can have some small constant percentage discount. So let's see how we can implement this as well. Oscar conditional offer is very tight with the condition so if you do not have condition which is stored in the condition model you cannot proceed with the discount so we have to work it around so there is an empty condition and also there are some changes necessary in the conditional offer model. So let's see how we will assign this discount for the user. We can use a membership model which will have title and offer. The offer is this conditional offer which is a center around this all discounting system. User has only one change. Membership. So here in the offer applicator we see that we just add the two lines. If user has membership if we show a list of this offer. Another one. Bonus system. Bonus system could be treated like if you buy some specific products. For each product you can get some bonus points which you can use later on for the purchases. It could be done by the seller to encourage people to buy certain products. And afterwards the customer will be rewarded the bonuses and they can be spent. Alright, so we add a bonus points field, which is this math field, to the product model. And And we also implement a signal receiver, which will be waiting for the purchases, and as soon as order placed, we sum up all the bonuses from those products that we have bought. And we just sum up them and increase the bonus points with this value. All right, later on, you will also need to implement payment gateway, which will allow for user to pay with the bonuses. There's also a necessity to provide gift cards. There is a ready-made application called Django Oscar Accounts, which could work basically with a conjunction with a bonus system, because it allows to directly provide a change of the payments. All right. But this is a key bit about the discounts. in the marketplace where products are supplied by the different vendors you need to be careful because supplier 1 could be providing a discount for his products and supplier 2 may not be providing so you as a platform will be providing discounts on the user basket on your own cost if you do not differentiate this on the basket level. All right. So, also, we need to integrate invoices. So, the invoices can be done by the ready-made application Django and the fast build. The fast build is a German service which is pretty much suitable. You send there your supplier details, order details and they take care of the invoices from end to end. Also, if you have delayed payments, you may need to notify your clients to pay if they miss the payment date and receive also a German service that we use on our project called onlinevif24.de. Alright, so We have small particular plans within the next few years to revise communication inside the OSCAR and to make a consolidated application in order to send all notifications and so on. Also, we want to extract promotions, which is an application to manage some banners and so on, to the external package, and this will allow you to easily integrate Django CMS, Vectail, and so on. Also, currently, Oscar uses Sorl, and we want to provide for the developers the ability to integrate any kind of seminal backend, which we are working on right now. The same also for the full-text search backend, we currently use Django Headstack, but we We are working on the direct Elastic DSL integration because we are pretty much limited when we need to upgrade and the packages that we use are not compatible with the latest Django right now. So the future, I suppose if more and more developers use a combined approach and utilize more API, then we probably do not need views, templates, and so on inside the core Oscars. So we're thinking about the potential of extracting the core functionality into one package that might be called Django Oscar Core. And the second package is with all the presentations, use forms, templates called Django Oscar Storefront and the dashboard. The dashboard is pretty much big by itself, so it does not make sense also to extract it. All right. Any questions? Thank you. So what is the biggest Oscar deployment that you know of? Not sure. I mean, I think that that's probably a question to David Winterbottom and Mike Hoffel because they originally implemented some heavy OSCQR sites, but we are working rather with the complex workflows. There are bottlenecks in the OSCQR because when you display a catalog, you need to check a stock record for each product that you display in it also to build the category tree and I mean if you cache all of this and probably tell us the API it should be pretty much good but we didn't test on the very big load if you mean some hundreds of thousands of use I think it's pretty much doable but we didn't try thank you I have another question how do you interact with with warehouses let's say that your store With the warehouses, the suppliers can access the dashboard and they can edit the product stock records by themselves. There is a stock record model where you store the number of items in stock, how many were bought, and how many have left. But there is no integration. You may want to have an integration with the warehouse software. We don't have it yet. But I suppose this should not be complex. You can fetch the data from the warehouse software, parse it, extract the products, find them by SKU or UPS in the database, take related stock record, and then update number of the products in stock. Thank you. So what is the approximate time to build or to build and integrate Django OSCAR to a standalone Django. You mean to develop for e-commerce projects on top of the Django instead of the Oscar? Or you want a comparison between... How much time does it save Oscar? Yeah, I mean, you said that with few GS, you said that it's simple. We can, for example, for a simple e-commerce platform. For the simple e-commerce platform, instead of masterminds for the frontend, I think it's doable in the, I suppose, three weeks instead of this. Because, I mean, in the single-page application, imagine you need to develop all the frontend by yourself to manage all the states within the Redux and so on. And in the hybrid approach, you can just take templates, implement some React components, And if you, for example, need to attach this component to the page, so you do not implement new templates and so on. Regarding the development time, standalone Django application versus Oscar, I suppose it's also around three months, I would say, maybe four. The thing is that there is also a kind of cons of the OSCQR. If you have a very custom workflow, checkout flow, you may need better to implement your e-commerce project from scratch because OSCQR is a little bit tight within the standard checkout flow, like at product.basket then proceed with the payment and so on so like shipping method. So if you need to customize a lot of things here, baskets, checkout and so on, that doesn't make sense to implement from scratch. Also, there is also example when you... Oscar is the best when you have a a stock and for example you can indicate how many products you sold but if you have a like a rental marketplace where you allow your customers to rent you do not have a stock because you know how many products for example bicycles you allow to take the rent but you do not know which ones are particularly available. So you need to determine when they are available, for example, from tomorrow to next week or today from 10 a.m. to 12 a.m. So in these cases, we do not use OSCAR. So if I want to integrate OSCAR, what is the most time-consuming for the basic workflow? is the most time consuming this chain of implementing basket models, middleware and so on and checkout so order creation and so on so this is the core functionality that always necessary in terms of discounts you may use them or you may not need the discounts all right do you have any other questions no so thank you alexander thank you for listening

Alexander Gaevsky

Django consultant from Ukraine with 7yrs+ experience, Django-Oscar core developer and open-source contributor.

Social card for talk: Developing ecommerce platform with Django Oscar