前回の記事「ゼロからはじめる Django で ECサイト構築(その1:ECパッケージの選定)」では、Django ベースの ECパッケージを選定し、「Django Oscar」が圧倒的人気で最有力候補であることが確認できました。
<過去記事>
akiyoko.hatenablog.jp
今回、「ゼロからはじめる Django で ECサイト構築」シリーズの第二回では、実際に、Django Oscar の Sandbox サイトを構築していくことにします。
Django Oscar について
概要
Django Oscar は、ECサイトを構築・運営するために必要な多くの機能が盛り込まれた、オープンソースで Django 製の ECパッケージです。ライセンスは修正BSDライセンス(New BSD license)で、商用利用も可能です。
機能の詳細については、次回以降にまとめていく予定です。
ECサイト構築に必要な三要素
さて、ECサイトを構築するためには、
- 決済代行サービスのマーチャントアカウント
- ECパッケージ
- サーバ
の三つが必要最低限の要素として挙げられるでしょう。
まず一つ目の「決済代行サービスのマーチャントアカウント」は、PayPal や WebPay などの決済代行サービスのビジネスアカウント(売り手アカウント)を指します。Sandbox 環境においては、Sandbox(ややこしいですが、決済代行サービス側が用意してくれるテスト環境を指します)用のマーチャントアカウントを使用することで、実際に支払いをすることなく決済処理の流れをシミュレートすることができます。
今回の検証では、決済代行サービスとして PayPal を利用するのですが、Sandbox については次のように説明されています。
ペイパルでは、決済サービスの動作確認ができるテスト環境として、Sandboxを公開しています。
テスト用の「Buyer(買い手)」アカウントと、「Seller(売り手)」アカウントを作成し、サービスの導入から、決済の流れまで、詳細にシミュレーションすることができます。
二つ目の ECパッケージについては、前回の選定で最有力候補となった「Django Oscar」を使用します。なお、決済モジュールには「django-oscar-paypal」を使用することとします。
三つ目のサーバについては、今回の Sandbox サイトでは仮想環境(Vagrant 上の Ubuntu 仮想マシン)を利用します。
Sandbox サイトの構築手順
ここから実際に、Django Oscar の Sandbox サイトを構築していきます(2016/5/28 バージョン)。
構築する環境は以下となります。
- サーバ:Ubuntu 14.04TLS(on Vagrant)
- Python 2.7.6
- Django 1.9.6(現時点の最新バージョン)
- ECパッケージ:Django Oscar 1.2+(現時点の最新バージョン)
- 決済モジュール:django-oscar-paypal 0.9.7(現時点の最新バージョン)
以降、次のような手順で進めていきます。
1. サーバの初期設定
私は通常、PyCharm Professional Edition の
- Vagrant 連携機能
- サーバとのソースコード同期機能
- リモートデバッグ機能
などの機能を利用するために、PyCharm を使っています。なので、いつもなら
- PyCharm の設定
- Pure Python Project を作成(空っぽのプロジェクトを作成)
- Vagrant連携
という流れで、PyCharm から Ubuntu サーバを立ち上げています。
<過去記事>
akiyoko.hatenablog.jp
手動でやるなら、以下のコマンドを実行します。
$ cd ~/PycharmProjects/oscar_sandbox/ $ vagrant init ubuntu/trusty64
仮想マシンに固定 IPアドレスを付けるために、Vagrantfile を書き換えます。
config.vm.network "private_network", ip: "192.168.33.105"
仮想マシンを起動します。
$ vagrant up
Vagrant サーバに ssh で乗り込みます。
$ ssh vagrant@192.168.33.105
1.2. MySQL をインストール
Ubuntu サーバに MySQL をインストールします。
$ sudo apt-get -y install mysql-server (root/rootpass) $ sudo apt-get -y install mysql-client libmysqlclient-dev python-mysqldb $ mysql --version mysql Ver 14.14 Distrib 5.5.49, for debian-linux-gnu (x86_64) using readline 6.3 $ sudo mysql_install_db ### 文字化け対策(セクションの最後に以下の設定を追加) ### http://blog.snowcait.info/2014/06/04/mariadb-utf8/ $ sudo vi /etc/mysql/my.cnf --- [mysqld] ・ ・ # ssl-ca=/etc/mysql/cacert.pem # ssl-cert=/etc/mysql/server-cert.pem # ssl-key=/etc/mysql/server-key.pem # Character set settings character-set-server = utf8 [mysqldump] ・ ・ --- $ sudo service mysql restart $ sudo mysql_secure_installation Enter current password for root (enter for none): Change the root password? [Y/n] n Remove anonymous users? [Y/n] Y Disallow root login remotely? [Y/n] Y Remove test database and access to it? [Y/n] Y Reload privilege tables now? [Y/n] Y
1.3. データベースを作成
データベース、データベースユーザを作成します。
なお、データベース名は Djangoプロジェクト名と合わせて myproject とします。
データベース名 | myproject |
データベースユーザ | myprojectuser |
データベースユーザパスワード | myprojectuserpass |
$ mysql -u root -p mysql> create database myproject character set utf8; mysql> create user myprojectuser@localhost identified by "myprojectuserpass"; mysql> grant all privileges on myproject.* to myprojectuser@localhost; mysql> flush privileges; mysql> exit
1.4. pip をインストール
Python 2.7.9 以降であれば pip がバンドルされているのですが、Ubuntu 14.04LTS では Python 2.7.6 が標準なので、手動でインストールします。
「sudo apt-get -y install python-pip」でインストールすると pip のバージョンが古いので、get-pip.py で最新版を入れることにします。
$ wget https://bootstrap.pypa.io/get-pip.py $ sudo -H python get-pip.py $ pip --version pip 8.1.2 from /usr/local/lib/python2.7/dist-packages (python 2.7)
参考
- python - What is the official "preferred" way to install pip and virtualenv systemwide? - Stack Overflow
- Myself ✪ Renoir Boulanger, Web Developer & Operations engineer
- How to Install Pip on Ubuntu 14.04 LTS – Liquid Web Knowledge Base
1.5. virtualenv, virtualenvwrapper をインストール
### virtualenv, virtualenvwrapper をインストール $ sudo -H pip install virtualenv virtualenvwrapper ### virtualenvwrapper の設定 $ cat << EOF >> ~/.bash_profile if [ -f ~/.bashrc ]; then . ~/.bashrc fi EOF $ cat << EOF >> ~/.bashrc source /usr/local/bin/virtualenvwrapper.sh export WORKON_HOME=~/.virtualenvs EOF $ source ~/.bashrc
2. Sandbox サイト(Django Oscar)の作成
2.1. Django Oscar プロジェクトを構築
Setting up the development environment — django-oscar 1.3 documentation
に従って、Oscar プロジェクトのインストールをします。
### Djangoプロジェクトの virtualenv 環境を設定して activate $ mkvirtualenv myproject ### /opt/webapps 配下にプロジェクトの外箱を作成 $ sudo mkdir -p /opt/webapps/myproject $ sudo chown -R `whoami`. /opt/webapps ### JPEG Support ### http://django-oscar.readthedocs.org/en/latest/internals/contributing/development-environment.html#jpeg-support $ sudo apt-get -y install libjpeg-dev libfreetype6-dev zlib1g-dev ### make sandbox をした後であれば ↓ を実行して Pillow を再インストール ### pip install --no-cache-dir -I pillow ### http://qiita.com/tototoshi/items/7b74fe26eb7bf39be7b5 ### MySQLライブラリのインストール ###($ pip install MySQL-python でも OK) $ pip install mysqlclient ### Oscar プロジェクトを作成 $ cd /opt/webapps/myproject/ ### 通常であれば、django-admin.py startproject . とするところを、今回は clone -> make sandbox として Sanbox サイトを作成 ### http://django-oscar.readthedocs.org/en/latest/internals/getting_started.html $ git clone https://github.com/django-oscar/django-oscar.git .
ここで、
###$ git checkout 1.2
として、最新の stable バージョン (1.2) に合わせようとしましたが、make sandbox 実行時に、
django.db.utils.OperationalError: (2013, 'Lost connection to MySQL server during query')
というエラーになってしまったので、master のままで試すことにしました(2016/5/28 時点)。
ちなみに、現時点の最新コミットは以下の通りです。
commit 156a4b814d540bb1c6216b757cfa4441b36f8077
Merge: e1a8ea7 de633f8
Author: Michael van Tellingen
Date: Wed Apr 13 09:03:37 2016 +0200Merge pull request #2030 from crgwbr/fix_broken_py3_migrations
Fix makemigrations in Python 3
### MySQL用の設定変更 $ vi sites/sandbox/settings.py <変更前> --- DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': location('db.sqlite'), 'USER': '', 'PASSWORD': '', 'HOST': '', 'PORT': '', 'ATOMIC_REQUESTS': True } } --- ↓ <変更後> --- DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'myproject', 'USER': 'myprojectuser', 'PASSWORD': 'myprojectuserpass', 'HOST': 'localhost', 'PORT': '', 'ATOMIC_REQUESTS': True } } --- ### Sandbox プロジェクトを作成 ### プロジェクトのディレクトリ構造は ### myproject/ (as <repository_root>) ### └─ sites/sandbox/ (as <django_project_root> also as <configuration_root>) $ make sandbox
ちなみに、make sandbox の処理はこのようになっています。
Makefile(抜粋)
install: pip install -e . -r requirements.txt build_sandbox: # Remove media -rm -rf sites/sandbox/public/media/images -rm -rf sites/sandbox/public/media/cache -rm -rf sites/sandbox/public/static -rm -f sites/sandbox/db.sqlite # Create database sites/sandbox/manage.py migrate # Import some fixtures. Order is important as JSON fixtures include primary keys sites/sandbox/manage.py loaddata sites/sandbox/fixtures/child_products.json sites/sandbox/manage.py oscar_import_catalogue sites/sandbox/fixtures/*.csv sites/sandbox/manage.py oscar_import_catalogue_images sites/sandbox/fixtures/images.tar.gz sites/sandbox/manage.py oscar_populate_countries sites/sandbox/manage.py loaddata sites/_fixtures/pages.json sites/_fixtures/auth.json sites/_fixtures/ranges.json sites/_fixtures/offers.json sites/sandbox/manage.py loaddata sites/sandbox/fixtures/orders.json sites/sandbox/manage.py clear_index --noinput sites/sandbox/manage.py update_index catalogue sandbox: install build_sandbox
Sandbox の作成が完了したら、作成状況を確認してみます。
$ pip list | grep Django Django (1.9.6) $ pip list | grep django-oscar django-oscar (1.3.dev0, /opt/webapps/myproject/src) $ pip freeze alabaster==0.7.8 apipkg==1.4 Babel==2.3.4 beautifulsoup4==4.4.1 coverage==3.7.1 coveralls==0.4.4 decorator==4.0.9 Django==1.9.6 django-debug-toolbar==1.4 django-extensions==1.6.1 django-extra-views==0.6.4 django-haystack==2.4.1 -e git+https://github.com/django-oscar/django-oscar.git@156a4b814d540bb1c6216b757cfa4441b36f8077#egg=django_oscar django-tables2==1.0.7 django-treebeard==4.0.1 django-webtest==1.7.8 django-widget-tweaks==1.4.1 docopt==0.6.2 docutils==0.12 execnet==1.4.1 factory-boy==2.6.1 fake-factory==0.5.7 flake8==2.5.1 flake8-blind-except==0.1.0 flake8-debugger==1.4.0 funcsigs==1.0.2 ipaddress==1.0.16 ipdb==0.8.1 ipython==4.0.1 ipython-genutils==0.1.0 isort==4.2.2 Jinja2==2.8 MarkupSafe==0.23 mccabe==0.3.1 mock==1.3.0 mysqlclient==1.3.7 nose==1.3.7 pathlib2==2.1.0 pbr==1.10.0 pep8==1.7.0 pexpect==4.1.0 phonenumbers==7.4.1 pickleshare==0.7.2 Pillow==2.7.0 pockets==0.3 ptyprocess==0.5.1 purl==1.3 py==1.4.31 pycountry==1.8 pyflakes==1.0.0 Pygments==2.1.3 pyprof2calltree==1.3.2 pysolr==3.2.0 pytest==2.8.5 pytest-cache==1.0 pytest-cov==2.2.0 pytest-django==2.9.1 pytest-xdist==1.13.1 python-dateutil==2.5.3 pytz==2016.4 PyYAML==3.11 requests==2.7.0 simplegeneric==0.8.1 six==1.10.0 snowballstemmer==1.2.1 sorl-thumbnail==12.4a1 spec==0.11.1 Sphinx==1.3.3 sphinx-rtd-theme==0.1.9 sphinxcontrib-napoleon==0.4.3 sqlparse==0.1.19 tox==1.8.1 traitlets==4.2.1 Unidecode==0.4.19 uWSGI==2.0.12 virtualenv==15.0.1 waitress==0.9.0 WebOb==1.6.1 WebTest==2.0.17 Werkzeug==0.9.6 whitenoise==2.0.6 Whoosh==2.6.0
$ find . -name "*.pyc" -exec rm -rf {} \; $ tree -a /opt/webapps/myproject/ -I ".git|docs|tests" -L 3 /opt/webapps/myproject/ ├── AUTHORS ├── CHANGELOG.rst ├── CONTRIBUTING.rst ├── .coveragerc ├── Dockerfile ├── .dockerignore ├── .gitignore ├── gulpfile.js │ ├── index.js │ └── tasks │ ├── default.js │ ├── less.js │ └── watch.js ├── LICENSE ├── lint.sh ├── .mailmap ├── Makefile ├── MANIFEST.in ├── package.json ├── README.rst ├── requirements_migrations.txt ├── requirements.txt ├── runtests.py ├── sandbox.yml ├── setup.cfg ├── setup.py ├── sites │ ├── _fixtures │ │ ├── auth.json │ │ ├── comms.json │ │ ├── offers.json │ │ ├── order-events.json │ │ ├── pages.json │ │ ├── promotions.json │ │ ├── range-products.csv │ │ └── ranges.json │ ├── README.rst │ └── sandbox │ ├── apps │ ├── deploy │ ├── fixtures │ ├── __init__.py │ ├── logs │ ├── manage.py │ ├── public │ ├── README.rst │ ├── settings_mysql.py │ ├── settings_postgres.py │ ├── settings.py │ ├── settings_sphinx.py │ ├── static │ ├── templates │ ├── test_migrations.sh │ ├── update_latest.sh │ ├── urls.py │ ├── whoosh_index │ └── wsgi.py ├── src │ ├── django_oscar.egg-info │ │ ├── dependency_links.txt │ │ ├── PKG-INFO │ │ ├── requires.txt │ │ ├── SOURCES.txt │ │ └── top_level.txt │ └── oscar │ ├── app.py │ ├── apps │ ├── core │ ├── defaults.py │ ├── forms │ ├── __init__.py │ ├── locale │ ├── management │ ├── models │ ├── profiling │ ├── static │ ├── templates │ ├── templatetags │ ├── test │ └── views ├── tox.ini ├── transifex.sh ├── .travis.yml └── .tx └── config 29 directories, 56 files
ここで一旦、データベースをバックアップしておきます。
### http://weblabo.oscasierra.net/mysql-mysqldump-01/ ### ちなみに、リストアするときは mysql -u root -p myproject < ~/myproject_init.dump $ mysqldump --single-transaction -u root -p myproject > ~/myproject_init.dump
2.2. Runserver で起動
$ python sites/sandbox/manage.py runserver 0.0.0.0:8000
でサーバを起動して、
http://192.168.33.105:8000/
にブラウザからアクセスします。
ログインユーザ
username: superuser
email: superuser@example.com
password: testing
username: staff
email: staff@example.com
password: testing
疎通ができたら、Runserver を一旦停止します。
ちなみにここまでの設定では、決済モジュールの設定をしていないので、決済処理を完了することができなくなっています。
(住所や電話番号などのダミー情報は、US Address Generator - Fake Address, Random Address Generator で生成したものを入力しました。)
このように、決済モジュール(payment gateway libraries)を設定してね、って怒られます。
以下、PyCharm を使う場合のメモです。PyCharm を使ってない方はすっ飛ばしてください。
- PyCharm の設定
- デプロイ先サーバ設定
- ソースコードの同期
- ローカル側でソースコードを Git管理
- Project Interpreter の設定
- Run/Debug設定(以下に詳細を記載)
Project ペインの manage.py ファイルで右クリック > [Create "manage"] を選択します。
Name | manage |
Script | sites/sandbox/manage.py |
Script parameters | runserver 0.0.0.0:8000 |
Environment variables | PYTHONUNBUFFERED=1(デフォルトのまま) |
Python interpreter | Project Default (Remote Python 2.7.6 Vagrant VM at ~/PycharmProjects/oscar_sandbox (/home/vagrant/.virtualenvs/myproject/bin/python)) |
Working directory | /opt/webapps/myproject |
Path mappings - Local path | /Users/akiyoko/PycharmProjects/oscar_sandbox |
Path mappings - Remote path | /opt/webapps/myproject |
ここで、「Add content roots to PYTHONPATH」と「Add source roots to PYTHONPATH」のチェックを外します。
要するに、Script のパスに気をつけてね、ってことです。
各種設定を確認
Sandbox サイトの settings.py を確認すると、以下のドキュメントに書かれている、既存サイトに追加する場合に追加する必要のある設定が全て追加されています。
http://django-oscar.readthedocs.org/en/latest/internals/getting_started.html
sites/sandbox/settings.py(抜粋)
・ ・ SITE_ID = 1 ・ ・ TEMPLATE_CONTEXT_PROCESSORS = ( "django.contrib.auth.context_processors.auth", "django.core.context_processors.request", "django.core.context_processors.debug", "django.core.context_processors.i18n", "django.core.context_processors.media", "django.core.context_processors.static", "django.contrib.messages.context_processors.messages", # Oscar specific 'oscar.apps.search.context_processors.search_form', 'oscar.apps.promotions.context_processors.promotions', 'oscar.apps.checkout.context_processors.checkout', 'oscar.core.context_processors.metadata', 'oscar.apps.customer.notifications.context_processors.notifications', ) MIDDLEWARE_CLASSES = ( 'debug_toolbar.middleware.DebugToolbarMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware', # Allow languages to be selected 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', # Ensure a valid basket is added to the request instance for every request 'oscar.apps.basket.middleware.BasketMiddleware', # Enable the ProfileMiddleware, then add ?cprofile to any # URL path to print out profile details #'oscar.profiling.middleware.ProfileMiddleware', ) ・ ・ # Add another path to Oscar's templates. This allows templates to be # customised easily. from oscar import OSCAR_MAIN_TEMPLATE_DIR TEMPLATE_DIRS = ( location('templates'), OSCAR_MAIN_TEMPLATE_DIR, ) ・ ・ INSTALLED_APPS = [ 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.admin', 'django.contrib.flatpages', 'django.contrib.staticfiles', 'django.contrib.sitemaps', 'django_extensions', # Debug toolbar + extensions 'debug_toolbar', 'apps.gateway', # For allowing dashboard access 'widget_tweaks', ] from oscar import get_core_apps INSTALLED_APPS = INSTALLED_APPS + get_core_apps() # Add Oscar's custom auth backend so users can sign in using their email # address. AUTHENTICATION_BACKENDS = ( 'oscar.apps.customer.auth_backends.EmailBackend', 'django.contrib.auth.backends.ModelBackend', ) ・ ・
INSTALLLED_APPS に
- django.contrib.sites
- django.contrib.flatpages
が追加されていて、MIDDLEWARE_CLASSES に
- oscar.apps.basket.middleware.BasketMiddleware
- django.contrib.flatpages.middleware.FlatpageFallbackMiddleware
が追加されていることが確認できます。
ちなみに、「TEMPLATE_CONTEXT_PROCESSORS」と「TEMPLATE_DIRS」を分けて記述している Sandbox の setteings.py の書き方は、Django 1.9 の書き方としては少し古いようですね。
Before Django 1.8 this setting was split between TEMPLATE_CONTEXT_PROCESSORS and TEMPLATE_DIRS.
http://django-oscar.readthedocs.org/en/latest/internals/getting_started.html
決済モジュールの導入手順
続けて、Django Oscar の Sandbox サイトに決済モジュールを組み込んでいきます。
決済代行サービスに「PayPal」を利用することを想定して、決済モジュールには「django-oscar-paypal」を選択することにします。
手順は以下の通りです。
- 1. PayPal の Test API Credentials を取得
- 2. django-oscar-paypal のインストール
- 2. INSTALLED_APPS に追加
- 4. マイグレーション
- 5. settings を修正
- 6. urls.py を修正
- 7. テンプレートファイルを修正
参考
http://django-oscar-paypal.readthedocs.org/en/latest/
1. PayPal の Test API Credentials を取得
PayPal の決済モジュールを利用するには、「Test API Credentials」という PayPal の決済API を利用するための認証情報が必要となります。
「Test API Credentials」は、以下の 3セットのキー・バリューとなっています。
- PAYPAL_API_USERNAME
- PAYPAL_API_PASSWORD
- PAYPAL_API_SIGNATURE
Test API Credentials を取得する前に、まずは PayPal のアカウントを取得します。本番ではビジネスアカウントが必要ですが、Sandbox では個人アカウントでも大丈夫です。
PayPal アカウントを取得した後に、「PayPal Developer」ページからログインします。
https://developer.paypal.com/
Sandbox アカウントではなく、通常の PayPal アカウントでログインします。
「DASHBOARD」をクリックします。
「Accounts」を選択します。
Sandbox 用の「Buyer アカウント(マーチャントアカウント)」と「Seller アカウント(買い手アカウント)」がデフォルトで用意されている(はずな)ので、Type が「BUSINESS」となっている方の Buyer アカウントの「Profile」をクリックします。
「API Credentials」タブから Test API Credentials を確認することができます。
参考(PayPal 公式)
参考(Test API Credentials)
参考(ビジネスアカウント)
- https://www.paypal.jp/cms/templates/jp_3rd_global_side.aspx?pageid=10737418282
- クレジットカード決済の導入-PayPal(ペイパル)
2. django-oscar-paypal のインストール
Ubuntu サーバ側で、django-oscar-paypal をインストールします。
$ workon myproject $ pip install django-oscar-paypal
- django-localflavor==1.3
- django-oscar-paypal==0.9.7
が追加されました。
3. INSTALLED_APPS に追加
sites/sandbox/settings.py に「paypal」を加えます。
INSTALLED_APPS = [ 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.admin', 'django.contrib.flatpages', 'django.contrib.staticfiles', 'django.contrib.sitemaps', 'django_extensions', # Debug toolbar + extensions 'debug_toolbar', 'paypal', 'apps.gateway', # For allowing dashboard access 'widget_tweaks', ]
4. マイグレーション
以下のコマンドを実行して、django-oscar-paypal 系のテーブルを作成します。
$ python sites/sandbox/manage.py migrate --run-syncdb Operations to perform: Synchronize unmigrated apps: reports_dashboard, messages, django_extensions, treebeard, gateway, communications_dashboard, reviews_dashboard, offers_dashboard, pages_dashboard, shipping_dashboard, haystack, promotions_dashboard, checkout, vouchers_dashboard, django_tables2, partners_dashboard, staticfiles, oscar, paypal, sitemaps, catalogue_dashboard, users_dashboard, search, debug_toolbar, widget_tweaks, dashboard, ranges_dashboard, orders_dashboard Apply all migrations: customer, promotions, shipping, wishlists, offer, admin, sessions, thumbnail, contenttypes, auth, payment, reviews, analytics, catalogue, flatpages, sites, address, basket, partner, order, voucher Synchronizing apps without migrations: Creating tables... Creating table paypal_expresstransaction Creating table paypal_payflowtransaction Running deferred SQL... Running migrations: No migrations to apply. Your models have changes that are not yet reflected in a migration, and so won't be applied. Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.
Django 1.9 の場合は、「run-syncdb」オプションを付けないとテーブルが作成されないので要注意です。(最後の警告は無視して OK。対応したいのであれば、makemigrations を実行すればよい。)
参考
http://stackoverflow.com/a/34635951
ここで、
- paypal_expresstransaction
- paypal_payflowtransaction
というテーブルが追加されました。
ここでもう一度、データベースをバックアップしておきます。
$ mysqldump --single-transaction -u root -p myproject > ~/myproject_migrate_paypal.dump
5. settings を修正
ここからは、
http://django-oscar-paypal.readthedocs.org/en/latest/express.html#getting-started
を参考にして進めていきます。
https://github.com/django-oscar/django-oscar-paypal/blob/master/sandbox/settings.py
を参考に、settings.py を修正します。
sites/sandbox/settings.py の最後の方に、以下の設定を追加します。
・ ・ # django-oscar-paypal # =================== PAYPAL_SANDBOX_MODE = True PAYPAL_CALLBACK_HTTPS = False PAYPAL_API_VERSION = '119' PAYPAL_API_USERNAME = '' PAYPAL_API_PASSWORD = '' PAYPAL_API_SIGNATURE = '' from django.utils.translation import ugettext_lazy as _ OSCAR_DASHBOARD_NAVIGATION.append( { 'label': _('PayPal'), 'icon': 'icon-globe', 'children': [ { 'label': _('Express transactions'), 'url_name': 'paypal-express-list', }, ] }) # Try and import local settings which can be used to override any of the above. try: from settings_local import * except ImportError: pass
次に、sites/sandbox/settings_local.py に、「1. PayPal の Test API Credentials を取得」で取得したマーチャントアカウントの APIキーを設定します。
PAYPAL_API_USERNAME = 'xxxxxx-facilitator_api1.xxxxxx.xxx' PAYPAL_API_PASSWORD = 'xxxxxxxxxxxxxxxx' PAYPAL_API_SIGNATURE = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
6. urls.py を修正
https://github.com/django-oscar/django-oscar-paypal/blob/master/sandbox/urls.py
を参考に、sites/sandbox/urls.py を修正します。
<修正前>
・ ・ from oscar.app import application from oscar.views import handler500, handler404, handler403 ・ ・ # Prefix Oscar URLs with language codes urlpatterns += i18n_patterns('', # Custom functionality to allow dashboard users to be created url(r'gateway/', include('apps.gateway.urls')), # Oscar's normal URLs url(r'', include(application.urls)), ) ・ ・
↓
<修正後>
・ ・ from oscar.app import application from oscar.views import handler500, handler404, handler403 from paypal.express.dashboard.app import application as express_dashboard ・ ・ # Prefix Oscar URLs with language codes urlpatterns += i18n_patterns('', # PayPal Express integration url(r'checkout/paypal/', include('paypal.express.urls')), # Dashboard views for Express url(r'dashboard/paypal/express/', include(express_dashboard.urls)), # Custom functionality to allow dashboard users to be created url(r'gateway/', include('apps.gateway.urls')), # Oscar's normal URLs url(r'', include(application.urls)), ) ・ ・
7. django-oscar-paypal のテンプレートファイルを修正
Django Oscar の basket(ショッピングカート)機能、および checkout(チェックアウト)機能で使われている各種テンプレートファイルに対して、以下の修正を行います。
- Django 1.9 対応(django-oscar-paypal が Django 1.9 に対応していないため)
- 体裁修正(django-oscar-paypal が Django Oscar のスタイルに対応していないため)
ここで、settings.py の設定が以下のようになっており、Sandbox プロジェクトの仕組み上、「sites/sandbox/templates/」 -> 「src/oscar/templates/oscar/」の順にテンプレートファイルをルックアップし、それでも無ければ、INSTALLED_APPS でインストールしたアプリケーションのテンプレートファイルを参照するようになっています。
from oscar import OSCAR_MAIN_TEMPLATE_DIR TEMPLATE_DIRS = ( location('templates'), OSCAR_MAIN_TEMPLATE_DIR, )
Sandbox プロジェクトでは、「src/oscar/templates/oscar/」配下に実ファイルを配置しているため、ライブラリが持っているテンプレートファイルによるオーバーライドが出来ないので注意が必要です。
1) ショッピングカート画面
django-oscar-paypal の Sandbox用に用意されているファイル
https://github.com/django-oscar/django-oscar-paypal/blob/master/sandbox/templates/basket/partials/basket_content.html
を sites/sandbox/templates/ 配下にコピーします。
$ cd /tmp/ $ git clone https://github.com/django-oscar/django-oscar-paypal.git $ cd django-oscar-paypal/ $ git checkout 0.9.7 $ mkdir -p /opt/webapps/myproject/sites/sandbox/templates/basket/partials $ cp -a sandbox/templates/basket/partials/basket_content.html /opt/webapps/myproject/sites/sandbox/templates/basket/partials/basket_content.html
2016/5/28 現時点の django-oscar-paypal のソースコードのままでは、以下のようにエラーが出てしまいます。
テンプレート内で、
{% load url from future %}
と書くと、Django 1.9 で動かした場合に、
'url' is not a valid tag or filter in tag library 'future'
というエラーが発生します。これは、Django1.9 以降では、future タグの url がなくなって、ビルトインのものを使うようになったからです。なので、Django1.9 以降では、url を load する必要は無く、
{% url 'checkout:preview' %}
とそのまま使えばよいです。
参考
https://www.bountysource.com/issues/29762758-django-1-9-compatibility-url-tag
要するに、django-oscar-paypal のテンプレートが Django 1.9 対応されていないのが原因なので、以下のように修正していきます。
sites/sandbox/templates/basket/partials/basket_content.html
<修正前>
{% extends 'oscar/basket/partials/basket_content.html' %} {% load url from future %} {% load i18n %} {% block formactions %} <div class="form-actions"> {% if anon_checkout_allowed or request.user.is_authenticated %} {% if basket.total_excl_tax > 0 %} <a href="{% url 'paypal-redirect' %}"><img src="https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif" align="left" style="margin-right:7px;"></a> {% endif %} {% endif %} <a href="{% url 'checkout:index' %}" class="pull-right btn btn-large btn-primary">{% trans "Proceed to checkout" %}</a> </div> {% endblock formactions %}
↓
<修正後>
{% extends 'oscar/basket/partials/basket_content.html' %} {#{% load url from future %}#} {% load i18n %} {% block formactions %} <div class="form-actions"> {% if anon_checkout_allowed or request.user.is_authenticated %} {% if basket.total_excl_tax > 0 %} <a href="{% url 'paypal-redirect' %}"><img src="https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif" align="left" style="margin-right:7px;"></a> {% endif %} {% endif %} <a href="{% url 'checkout:index' %}" class="pull-right btn btn-large btn-primary">{% trans "Proceed to checkout" %}</a> </div> {% endblock formactions %}
上記の対応後、ショッピングカート画面を確認すると、以下のように表示が少し崩れてしまっています。
こちらは、Django Oscar 側のテンプレートのスタイルの当て方が変わったのに、django-oscar-paypal の Sandbox 用のテンプレート側がまだ対応できていないことが原因のようです。
そこで、src/oscar/templates/oscar/basket/partials/basket_content.html を参考にして、以下のようにテンプレートファイルを修正します。
<再修正後>
{% extends 'oscar/basket/partials/basket_content.html' %} {#{% load url from future %}#} {% load i18n %} {% block formactions %} <div class="form-actions"> <div class="row"> <div class="col-sm-8"> {% if anon_checkout_allowed or request.user.is_authenticated %} {% if basket.total_excl_tax > 0 %} <a href="{% url 'paypal-redirect' %}"><img src="https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif" align="left" style="margin-right:7px;"></a> {% endif %} {% endif %} </div> <div class="col-sm-4"> <a href="{% url 'checkout:index' %}" class="btn btn-lg btn-primary btn-block">{% trans "Proceed to checkout" %}</a> </div> </div> </div> {% endblock formactions %}
これで、きちんと表示されるようになりました。
2) チェックアウト画面
同じように、
https://github.com/django-oscar/django-oscar-paypal/blob/master/sandbox/templates/checkout/payment_details.html
を sites/sandbox/templates/ 配下にコピーします。
$ cd /tmp/django-oscar-paypal/ $ mkdir -p /opt/webapps/myproject/sites/sandbox/templates/checkout $ cp -a sandbox/templates/checkout/payment_details.html /opt/webapps/myproject/sites/sandbox/templates/checkout/payment_details.html
こちらも、同様のエラーが出るので、
以下のように修正を加えます。
sites/sandbox/templates/checkout/payment_details.html
<修正前>
{% extends 'oscar/checkout/payment_details.html' %} {% load url from future %} {% load i18n %} {% block payment_details %} <div class="well"> <div class="sub-header"> <h3>{% trans "PayPal Express" %}</h3> </div> <p>{% trans "Click on the below icon to use Express Checkout but where the shipping address and method is already chosen on the merchant site." %}</p> <div style="overflow:auto"><a href="{% url 'paypal-direct-payment' %}" title="{% trans "Pay with PayPal" %}"><img src="https://www.paypal.com/en_US/i/logo/PayPal_mark_37x23.gif" align="left" style="margin-right:7px;"></a> </div> </div> <div class="well"> <div class="sub-header"> <h3>{% trans "PayPal PayFlow Pro" %}</h3> </div> <form method="post" action="{% url 'checkout:preview' %}" class="form-stacked"> {% csrf_token %} <h4>{% trans "Bankcard" %}</h4> {% include "partials/form_fields.html" with form=bankcard_form %} <h4>{% trans "Billing address" %}</h4> {% include "partials/form_fields.html" with form=billing_address_form %} <div class="form-actions"> <button type="submit" class="btn btn-large btn-primary">{% trans "Continue" %}</button> </div> </form> </div> {% endblock %}
↓
<修正後>
{% extends 'oscar/checkout/payment_details.html' %} {#{% load url from future %}#} {% load i18n %} {% block payment_details %} <div class="well"> <div class="sub-header"> <h3>{% trans "PayPal Express" %}</h3> </div> <p>{% trans "Click on the below icon to use Express Checkout but where the shipping address and method is already chosen on the merchant site." %}</p> <div style="overflow:auto"><a href="{% url 'paypal-direct-payment' %}" title="{% trans "Pay with PayPal" %}"><img src="https://www.paypal.com/en_US/i/logo/PayPal_mark_37x23.gif" align="left" style="margin-right:7px;"></a> </div> </div> <div class="well"> <div class="sub-header"> <h3>{% trans "PayPal PayFlow Pro" %}</h3> </div> <form method="post" action="{% url 'checkout:preview' %}" class="form-stacked"> {% csrf_token %} <h4>{% trans "Bankcard" %}</h4> {% include "partials/form_fields.html" with form=bankcard_form %} <h4>{% trans "Billing address" %}</h4> {% include "partials/form_fields.html" with form=billing_address_form %} <div class="form-actions"> <button type="submit" class="btn btn-large btn-primary">{% trans "Continue" %}</button> </div> </form> </div> {% endblock %}
ここでは詳しく触れませんが、日本では「PayPal PayFlow Pro」は使えないので、最終的なテンプレートファイルは以下のようにしておきます。
<再修正後>
{% extends 'oscar/checkout/payment_details.html' %} {#{% load url from future %}#} {% load i18n %} {% block payment_details %} <div class="well"> <div class="sub-header"> <h3>{% trans "PayPal Express" %}</h3> </div> <p>{% trans "Click on the below icon to use Express Checkout but where the shipping address and method is already chosen on the merchant site." %}</p> <div style="overflow:auto"><a href="{% url 'paypal-direct-payment' %}" title="{% trans "Pay with PayPal" %}"><img src="https://www.paypal.com/en_US/i/logo/PayPal_mark_37x23.gif" align="left" style="margin-right:7px;"></a> </div> </div> {% endblock %}
3) PayPal からのリダイレクト画面
続いて、PayPal での処理処理が終わったときにリダイレクトされてくる画面のテンプレートファイルを修正します。これまで同様に、
- Django 1.9 対応
- 体裁修正
の対応を行います。
$ cp -r /home/vagrant/.virtualenvs/myproject/lib/python2.7/site-packages/paypal/templates/* /opt/webapps/myproject/sites/sandbox/templates/ $ rm -rf /opt/webapps/myproject/sites/sandbox/templates/paypal/payflow $ tree sites/sandbox/templates/paypal/ sites/sandbox/templates/paypal/ └── express ├── dashboard │ ├── transaction_detail.html │ └── transaction_list.html └── preview.html
sites/sandbox/templates/paypal/express/preview.html
<修正前>
{% extends "checkout/preview.html" %} {% load currency_filters %} {% load i18n %} {% load url from future %} {% load thumbnail %} {# Null out the actions as they can't be used here #} {% block shipping_address_actions %}{% endblock %} {% block shipping_method_actions %}{% endblock %} {% block order_contents_actions %}{% endblock %} {% block payment_method %} <div class="span6"> <div class="sub-header"> <h2>{% trans "Payment" %}</h2> </div> <div class="well well-success"> <h4>{% trans "PayPal" %}</h4> <p> {% blocktrans with amt=paypal_amount|currency email=paypal_user_email %} {{ amt }} will be deducted from your PayPal account, registered to email: {{ email }}. {% endblocktrans %} </p> </div> </div> {% endblock %} ・ ・
↓
<修正後>
{% extends "checkout/preview.html" %} {% load currency_filters %} {% load i18n %} {#{% load url from future %}#} {% load thumbnail %} {# Null out the actions as they can't be used here #} {% block shipping_address_actions %}{% endblock %} {% block shipping_method_actions %}{% endblock %} {% block order_contents_actions %}{% endblock %} {% block payment_method %} <div class="col-sm-6"> <div class="sub-header"> <h2>{% trans "Payment" %}</h2> </div> <div class="well well-success"> <p>{% blocktrans with amount=order_total.incl_tax|currency %}<strong>{{ amount }}</strong> will be debited from your bankcard.{% endblocktrans %}</p> <div class="alert-actions"> <a href="{% url 'checkout:payment-details' %}" class="btn">{% trans "Change payment details" %}</a> </div> </div> </div> {% endblock payment_method %} ・ ・
4) ダッシュボード画面
Django Oscar のダッシュボード画面を使う場合は、以下の 2ファイルに Django 1.9 対応の修正を加える必要があります。
sites/sandbox/templates/paypal/express/dashboard/transaction_list.html
{% extends 'dashboard/layout.html' %} {% load currency_filters %} {% load i18n %} {#{% load url from future %}#} ・ ・
sites/sandbox/templates/paypal/express/dashboard/transaction_detail.html
{% extends 'dashboard/layout.html' %} {% load currency_filters %} {% load i18n %} {#{% load url from future %}#} ・ ・
以上で、Django Oscar の Sandbox サイトを構築するまでの作業は終了です。
GitHub にも修正内容をアップしたので、こちらも参照してください。
GitHub - akiyoko/oscar_sandbox
まとめ
やや細かな修正内容まで言及してしまいましたが、Django Oscar の Sandbox サイトを構築して、決済モジュールを導入するまでの手順を紹介しました。
これで、Django Oscar のいろいろな機能を試すことができるようになりました。次回は、この Sandbox サイトを使って、Django Oscar の ECサイトとしての機能を検証していきます。