Django, the (probably) most used full-stack web framework in Python. Oscar, (probably) the most vigorous e-commerce package that runs on Django.
I wrote the Oscar as a guide for using it in Japan.
Django-Oscar documentation: https://django-oscar.readthedocs.org/
Repository: https://github.com/django-oscar/django-oscar
--Since it runs on Python + Django environment, it is easy for experienced users to customize. --Works on Python3 --Django is ~~ latest ~~ 1.8 required. (Addition: 1.9 was released) --Modified BSD License (BSD 3-Clause License (Revised)). Same as Django. --With Bootstrap. It's responsive from the demo template. --Multilingual support. Japanese PO files are included from the beginning, but they are not so complete. --Multi-currency compatible. The currency type is a decimal number with a decimal point by default, so I was a little confused at first. --You can register addresses in various countries from the beginning. ――The payment system is not included at first, so you can either enter it with pip or write it yourself. --Flexible customization other than core code. For example, you can add fields to the model, change the behavior of the view, etc. without modifying the original code. (If you want to fix the core code, maybe a monkey patch or a repository fork ...) --The product (catalog) consists of three stages: class> product> inventory & price. --Inventory & charge classes can be set for each currency. --There is a category class. Category: Many products: Many ――The image of the product is usually uploaded from the site, and you cannot register the image in an external service and write only the URL in the model at first. Model customization and template modification required. --For tax rates, write the tax rate class in hard coding. --Style sheet is less --The administrator account that logs in to the management site and the general customer account will be created in the same model (table). Separate permissions by permission flag. If you want to separate this model, it seems quite difficult.
Functions included from the beginning
--Review function
Such.
It's relatively easy to turn off features such as reviews. (Available in settings)
By the way, the "point" function that is common in Japan is not included.
If you want to extend (inherit) the standard Oscar function, use a function called fork.
First, create a directory such as oscar_fork (or myapps) directly under the project.
$ ./manage.py oscar_fork_app catalogue oscar_fork
If you execute, oscar_fork / catalog will be created.
In this fork module
--Model extension --Extending and disabling views --Add or disable URLs
And so on.
For example, if you want to add a thumbnail_url field to catalog.Product
oscar_fork/catalogue/models.py
from django.db import models
from oscar.apps.catalogue.abstract_models import AbstractProduct
class Product(AbstractProduct):
image_url = models.URLField(default='', blank=True)
thumbnail_url = models.URLField(default='', blank=True)
from oscar.apps.catalogue.models import * # noqa
As INSTALLED_APPS
settings.py
INSTALLED_APPS = [
'django.contrib.admin',
....
]
INSTALLED_APPS += get_core_apps([
'oscar_fork.catalogue',
])
Extend INSTALLED_APPS by writing.
You can create a migration file with ./manage.py makemigrations
, so use ./manage.py migrate
to migrate the schema.
If you want to expand the view of your cart (checkout)
$ ./manage.py oscar_fork_app checkout oscar_fork
after
python:oscar_fork/checkout.views.py
from oscar.apps.checkout import views
class IndexView(views.IndexView):
def get(self, request, *args, **kwargs):
#get processing...
You can write like this.
Also added to INSTALLED_APPS
settings.py
INSTALLED_APPS += get_core_apps([
'oscar_fork.catalogue',
'oscar_fork.checkout',
])
If you want to add or disable URLs, write app.py.
$ ./manage.py oscar_fork_app customer oscar_fork
oscar_fork/customer/app.py
from oscar.apps.customer import app
class CustomerApplication(app.CustomerApplication):
def get_urls(self):
urls = [
# Login, logout and register doesn't require login
url(r'^login/$', self.login_view.as_view(), name='login'),
url(r'^logout/$', self.logout_view.as_view(), name='logout'),
# url(r'^register/$', self.register_view.as_view(),
# name='register'),
You can disable it by commenting out the register URL.
Also added to INSTALLED_APPS. (Details omitted)
settings.py
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
settings.py
OSCAR_DEFAULT_CURRENCY = 'JPY'
OSCAR_CURRENCY_FORMAT = '¤#,##0'
$ ./manage.py oscar_populate_countries
So, the country model (address_country) will contain the initial data for 249 countries.
If is_shipping_country is set to 1 for Japan only and 0 for others, the country name selection will not appear when registering an address (Japan will be the default).
From the Django shell or SQL.
mysql> UPDATE address_country SET is_shipping_country = 0 WHERE printable_name != 'Japan';
How do I translate Oscar? — django-oscar 0.5 documentation https://django-oscar.readthedocs.org/en/releases-0.5/howto/how_do_i_translate_oscar.html
Refer to here
$ mkdir locale i18n
$ ln -s $PATH_TO_OSCAR i18n/oscar
$ ./manage.py makemessages --symlinks --locale=ja
(If that doesn't work, maybe gettext isn't installed. In my case (mac) I needed brew install gettext --force)
Edit locale / ja / LC_MESSAGES / django.po
msgid "email address"
msgstr "mail address"
msgid "First name"
msgstr "Surname"
msgid "Last name"
msgstr "Name"
msgid "View basket"
msgstr "See the cart"
msgid "Basket total"
msgstr "total fee"
msgid "Basket total:"
msgstr "total fee:"
msgid "In stock"
msgstr "In stock"
msgid "Shipping"
msgstr "Shipping"
msgid "Total"
msgstr "subtotal"
msgid "Order total"
msgstr "total fee"
msgid "State/County"
msgstr "Prefectures"
msgid "City"
msgstr "Municipality"
msgid "First line of address"
msgstr "Town name/Character/address"
msgid "Second line of address"
msgstr "building/room number"
...
(* First name = surname, Last name = first name is intentionally written and is not wrong. This is easier for me to use.)
After writing the po file,
$ ./manage.py compilemessages
To create a mo file. The site is now displayed in Japanese.
The default is a fixed tax rate of 0%. The consumption tax in Japan is 8%, so it needs to be changed.
The tax rate is in partner / strategy.py
$ ./manage.py oscar_fork_app partner oscar_fork
after,
oscar_fork/partner/strategy.py
from decimal import Decimal as D
from oscar.apps.partner import strategy
class Selector(object):
def strategy(self, request=None, user=None, **kwargs):
return JPStrategy()
class JP(strategy.FixedRateTax):
rate = D('0.08')
exponent = D('1.')
def pricing_policy(self, product, stockrecord):
if not stockrecord:
return prices.Unavailable()
rate = self.get_rate(product, stockrecord)
exponent = self.get_exponent(stockrecord)
tax = (stockrecord.price_excl_tax * rate).quantize(
exponent, rounding=ROUND_DOWN)
return prices.TaxInclusiveFixedPrice(
currency=stockrecord.price_currency,
excl_tax=stockrecord.price_excl_tax,
tax=tax)
def parent_pricing_policy(self, product, children_stock):
stockrecords = [x[1] for x in children_stock if x[1] is not None]
if not stockrecords:
return prices.Unavailable()
# We take price from first record
stockrecord = stockrecords[0]
rate = self.get_rate(product, stockrecord)
exponent = self.get_exponent(stockrecord)
tax = (stockrecord.price_excl_tax * rate).quantize(
exponent, rounding=ROUND_DOWN)
return prices.FixedPrice(
currency=stockrecord.price_currency,
excl_tax=stockrecord.price_excl_tax,
tax=tax)
class JPStrategy(strategy.UseFirstStockRecord, strategy.StockRequired,
JP, strategy.Structured):
pass
You can write it like this.
class JP(strategy.FixedRateTax):
rate = D('0.08')
I wrote this. In this case, the amount after the decimal point is treated as it is. For example, in the case of a product of 70 yen excluding tax, it is calculated internally as 75.6 yen including tax. Consider the number after the decimal point.
This was inconvenient for my service, so I changed it as follows
class JP(strategy.FixedRateTax):
rate = D('0.08')
exponent = D('1.')
The numbers after the decimal point are rounded off. For products of 70 yen excluding tax, it will be 76 yen including tax.
This time, I wanted to truncate after the decimal point, so I overridden both the pricing_policy
and parent_pricing_policy
methods and put rounding = ROUND_DOWN
in the argument of the quantize
method of Decimal
.
It's not a bit elegant to override the entire method just because you wanted to truncate it. Is there any good way?
I wonder if it can be realized with decimal.setcontext
. I can't do it because it seems to have other effects.
Added to INSTALLED_APPS as usual
settings.py
INSTALLED_APPS += get_core_apps([
...
'oscar_fork.partner',
])
Since you can write branches etc. with logic, you can also write complicated processing. Tariffs etc.
I think that it can be used almost in Japan.
The rest is template creation and translation.
By the way. The top page is in promotions.
The views are ʻoscar.apps.promotions.views.HomeView, The template is
promotions / home.html`. It will take some time to find it, so I will write it down.
paypal seems to be relatively easy to use with the django-oscar-paypal
module. Supports express checkout and payflow. Maybe Express Checkout just gives you a link.
I decided to do it with webpay, so I wrote it myself.
You will be writing by overriding handle_payment
in payment.views.PaymentDetailsView
.