akiyoko blog

akiyoko の IT技術系ブログです

「一対一」「一対多」「多対多」のリレーションを分かりやすく説明する

こんにちは、akiyoko です。

今回はデータベース設計の話です。
分かりそうでよく分からない、「一対一」「一対多」「多対多」のリレーションを分かりやすく説明してみます。

f:id:akiyoko:20160801054222p:plain


一対一リレーション

f:id:akiyoko:20160731193333p:plain

分かりやすい定義

  • 双方のレコードが一対一に対応する

あるいは、

  • 双方の主キーが同じ


 

設計例

一対一リレーションは、分割しなくてもよいテーブルが分割されている状態です。既存のテーブル構成を変えずに項目を追加したい場合などを除き、積極的に使用する機会はあまり無いように思います。


 

一対多リレーション

f:id:akiyoko:20160731214014p:plain

分かりやすい定義

  • A のレコードは B の複数のレコードと関連する可能性があるが、B のレコードは A のレコードと最大一件のみ関連する

もう少し詳しく説明すると、

  • A から見れば、A の 1つのレコードが同時に複数の B のレコードと関連している(関連のないレコードもある)
  • B から見れば、B の 1つのレコードが A の 1つのレコードのみと関連している(関連のないレコードもある)

分かりやすい具体例

  • 例1)A:ブログの投稿者、B:ブログの投稿
  • 例2)A:顧客、B:注文
  • 例3)A:注文、B:注文明細
  • 例4)A:部署、B:従業員

 

設計例

A(一側)は、正規化によって B(多側)から分割されたテーブルである場合が多いです。

一対多リレーションでは、一側のテーブルの主キーを参照する外部キーを、多側のテーブルに設けて対応する場合が多いでしょう。


 

多対多リレーション

f:id:akiyoko:20160731193422p:plain

分かりやすい定義

  • A のレコードは B の複数のレコードと関連する可能性があり、B のレコードも A の複数のレコードと関連する可能性がある

もう少し詳しく説明すると、

  • A から見れば、A の 1つのレコードが同時に複数の B のレコードと関連している(関連のないレコードもある)
  • B から見れば、B の 1つのレコードが同時に複数の A のレコードと関連している(関連のないレコードもある)

 

分かりやすい具体例

  • 例1)A:ブログのカテゴリ、B:ブログの投稿 *1
  • 例2)A:ユーザ、B:権限 *2

 

設計例

多対多リレーションでは、双方に外部キーを設け、中間テーブルを利用するケースが多いでしょう。


 

*1:※投稿にはカテゴリが複数設定できるという前提

*2:※ユーザには権限が複数設定できるという前提

「SEO初心者に贈るWebライティング講座 ~キーワードからの記事作成編~」に参加しました

主催

株式会社クリーク・アンド・リバー社


会場

株式会社クリーク・アンド・リバー社
東京都千代田区一番町8番地 住友不動産一番町ビル 麹町制作ルーム5F


感想など

二週間以上経ってしまいましたが、今月中旬に「SEO初心者に贈るWebライティング講座 ~キーワードからの記事作成編~」というイベントに参加してきました。


イベントの内容は、

  • ① SEOを意識したWebライティングに欠かせない、キーワードの選定
  • ② キーワードの検索ボリュームやSEO難易度をチェック
  • ③ 複合語で絞り込むユーザーニーズと記事テーマ
  • ④ 設定キーワードを軸にした文章構成術

ということで、Webライティングにあたっての SEOノウハウについての
ちなみに有料(1,000円)でしたが、かなり盛り沢山の内容で気になっていたことも直接質問できたので、個人的には安いくらいでした。


最近、人の気持ちに訴えかけるライティングのコツを身につけるために、ライティングのレジェンドと言われているダン・ケネディの本を読んでみたのですが、今回の内容は、Google のランキングアルゴリズムに訴えかけるライティングのコツについての勉強会です。

究極のセールスレター シンプルだけど、一生役に立つ!お客様の心をわしづかみにするためのバイブル

究極のセールスレター シンプルだけど、一生役に立つ!お客様の心をわしづかみにするためのバイブル

  • 作者: ダン・ケネディ,神田昌典,齋藤慎子
  • 出版社/メーカー: 東洋経済新報社
  • 発売日: 2007/03/30
  • メディア: 単行本(ソフトカバー)
  • 購入: 22人 クリック: 143回
  • この商品を含むブログ (13件) を見る


SEO テクニックについては、少し前の「タイ全裸事件」で 辻正浩さんの Twitter をフォローしたのがきっかけで最近興味を持っていたのですが、SEO についての最新情報や全体像を確認しておきたいと思い、今回のイベントに参加した次第です。


講師は、現在フリーで Web制作・ライターをされている方で、これまで 10年くらい雑誌系のライターや Web制作をしながら、オンライン Webスクールの主催および、ブログ、SEOなどの講師等も歴任してきたとのことです。




メモ

  • Webライティングには 3つのポイント
    • タイトルと説明文
    • パッと見の印象(ファーストビュー)
    • 読みやすく、分かりやすい文章術
  • 被リンク(外部要因)も重要だが、Google はコンテンツ(内部要因)重視
    • 過去のパンダアップデート、ペンギンアップデートによって、業者が 3〜4年くらい前に壊滅状態に
    • コンテンツ is king.
  • テクニック
    • タイトルにサイトの最重要キーワードを必ず含める!
      • タイトルの頭の方に重要なキーワードを入れておく
    • タイトルは 30文字以内で!
    • タイトルは、単語の羅列ではなくきちんとした文章にする
    • タイトルの重複に注意!
    • 内容はユーザへの訴求力も必要
    • まず結論を
    • ユーザーにとってのメリット、ターゲットを明確に
      • 「何杯食べても太らない」「初心者のための」
    • 具体的な表現を。数字を入れると効果高い
    • meta description は SEO的にはもはや効果がないとされているが、SERPs に説明文として表示されるケースがあるので気をつけるべし
      • 検索語で説明文が変わることも
    • 見出しや本文でも適切にキーワードを使用する
    • 代名詞はなるべく使わず、一般名詞を(くどくならない範囲で)使うようにする
    • 内部リンクも SEO に影響するので、「こちら」にリンクを張らないように気をつける(リンク先の要約などにする)
    • 主要な画像には alt を入れる。キャプション(近くに説明文)もあった方がいい
    • 本文の文字数は多い方がいいが、最終的には質が大事
      • ミラーリングは嫌われる。オリジナル要素が重要
  • キーワード選定に役立つツール
  • 検索した人の意図を考えるべし!

Google Analytics の Kindle 本

Mac の MySQL クライアントに「Sequel Pro」を使っているなら PostgreSQL クライアントは「PSequel」がオススメ

タイトル通りですが、Mac の MySQL クライアントに「Sequel Pro」を使っているなのであれば、PostgreSQL クライアントは「PSequel」がオススメです。


長年、Mac の PostgreSQL クライアントに不満があり、使い勝手の良いアプリを探し求めていたのですが、ついにその答えを見つけたような気がします。

私が個人的に一番使い勝手が良いと思っている MySQL クライアントが「Sequel Pro」なのですが、その Sequel Pro の PostgreSQL 版とも言うべきアプリがこの「PSequel」なのです。


PSequel の作者も、このように言っています。

Well, pgAdmin is great for its feature-richness. However, I found its UI is clumsy and complicated. I know there is a list of PostgreSQL GUI Tools. However, they are either web-based, Java-based* or don't support the features I want. In the good old MySQL world, my favorite client is Sequel Pro, but its support for PostgreSQL doesn't seem to be happening. So, I decided to make one myself.


pgAdmin って機能が抱負で良いんだけどさ、UI がイケてないよね。他にも PostgreSQL の GUI ツールはいろいろあるんだけど、Web ベースだったり、Java ベースだったり、欲しい機能が無かったりでちょっとアレだよね。MySQL だったら、僕のお気に入りのクライアントは Sequel Pro なんだけど、どうやら PostgreSQL のサポートはしなさそうだし、じゃあ自分で作っちゃえって思っちゃったわけ。


(akiyoko 意訳)


 
さて今回は、PSequel の使い方、特に PostgreSQL への接続方法について紹介します。


そもそも実際のシステムでは、PostgreSQL 等のデータベースは通常、サーバの外にはポートは開放しておらず、SSH でリモートサーバに乗り込んでサーバ上のデータベースに接続するというパターンが多いでしょう。本番環境や検証環境では、公開鍵認証でログインすることが一般的でしょうが、開発環境では Vagrant 等で仮想サーバを利用することも多く、その場合はパスワード認証を使うこともあるでしょう。


そこで今回は、リモートサーバ上の PostgreSQL に SSH トンネル経由で接続する方法として、

  • 1)サーバに SSH公開鍵認証でログイン ⇒ サーバ上の PostgreSQL に接続
  • 2)サーバにパスワード認証でログイン ⇒ サーバ上の PostgreSQL に接続

という二つのパターンを紹介します *1


接続する PostgreSQL の設定は、以下の通りとします。

項目 設定内容
データベース名 myproject
データベースユーザ myprojectuser
データベースユーザパスワード myprojectuserpass


 

インストール

インストールするには、Homebrew で

$ brew cask install psequel

とするか、公式ページ から app ファイルをダウンロードしてインストールします。


www.psequel.com


 

PostgreSQL への接続

1)サーバに SSH公開鍵認証ログイン ⇒ サーバ上の PostgreSQL に接続

サーバに SSH公開鍵認証でログインして、SSHトンネル経由で PostgreSQL に接続する方法です。

本番環境(PostgreSQL on EC2)として、各種設定は以下を想定しています。

サーバ IPアドレス 52.100.100.100
ログインユーザ ubuntu
SSH秘密鍵 ~/.ssh/aws_p1.pem


f:id:akiyoko:20160729012558p:plain


2)サーバにパスワード認証ログイン ⇒ サーバ上の PostgreSQL に接続

サーバに SSH公開鍵認証でログインして、SSHトンネル経由で PostgreSQL に接続する方法です。

開発環境(PostgreSQL on Vagrant)として、各種設定は以下を想定しています。

サーバ IPアドレス 192.168.32.10
ログインユーザ vagrant
ログインパスワード vagrant


しかしながら、ここでハマりポイントがあります。
実は、PSequel はパスワード認証による SSHトンネリング機能をサポートしていないため(そして今後もサポートする予定は無さそう *2)、Vagrant のセッティングから SSH秘密鍵のパスを参照することができるという裏ワザ(?)を利用します。

The biggest requirement for a GUI of any sort (whether it is for a database client or something else), is the ability to use SSH tunneling to connect to the server. SSH tunneling allows an application to first connect to a machine (in this case a virtual machine managed by Vagrant), and act as normally as if it were connected directly to a service on your personal machine.


While PSequel does support SSH tunneling, what it does not do is support password authentication. I’m sure there was a good reason for this, but in the case of Vagrant it is irritating nontheless. Most Vagrant boxes have a default username and password (vagrant and vagrant respectively). This makes it incredibly simple to use applications that support SSH tunneling.


In the case of PSequel, the only authentication method that is supported is key authentication. Luckily for us, Vagrant does typically utilize this method of authentication (when you SSH into the Vagrant machine, for example, a private key is used so you don’t have to enter a password). Unfortunately for us, the location of this private key can be different for every machine. If you don’t know how to find it, using PSequel can seem impossible.


To find the private key for a Vagrant box, open up a terminal, navigate to the project folder, and type vagrant ssh-config. You’ll see something like this:


http://zacharyflower.com/using-psequel-with-vagrant/

操作は簡単で、Vagrant のホームに移動して「vagrant ssh-config」コマンドを実行すれば OK です。

$ cd vagrant/ubuntu14/
$ vagrant ssh-config
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2200
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/akiyoko/vagrant/ubuntu14/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL


 
これを利用して、以下の接続設定を行えばよいでしょう。

f:id:akiyoko:20160729012628p:plain

f:id:akiyoko:20160729012651p:plain


ただし正確に言えば、パスワード認証でサーバにログインできない問題が解決できたわけではないので、Vagrant 以外だったらどうするか?については今後の課題でしょうか。




ここからは、MySQL クライアントの「Sequel Pro」*3 の接続設定についてのメモです。

「Sequel Pro」の接続設定

1)サーバに SSH公開鍵認証ログイン ⇒ サーバ上の PostgreSQL に接続

本番環境(PostgreSQL on EC2)として、各種設定は以下を想定。

サーバ IPアドレス 52.100.100.100
ログインユーザ ubuntu
SSH秘密鍵 ~/.ssh/aws_p1.pem

f:id:akiyoko:20160729012257p:plain

2)サーバにパスワード認証ログイン ⇒ サーバ上の PostgreSQL に接続

開発環境(PostgreSQL on Vagrant)として、各種設定は以下を想定。

サーバ IPアドレス 192.168.32.10
ログインユーザ vagrant
ログインパスワード vagrant

f:id:akiyoko:20160729012527p:plain

*1:2015年1月より、PSequel に SSH トンネリング機能がサポートされました。https://twitter.com/psequel/status/550881414540173312

*2:https://github.com/psequel/psequel/issues/17

*3:ちなみに、Sequel は「シクォル」と発音するようです。

「PayPal Tech Meetup #2」に参加してきました

会場

イベント&コミュニティスペース dots.
東京都渋谷区宇田川町20-17 NOF渋谷公園通りビル 8F


Twitter

twitter.com


Togetter

togetter.com


感想など

今年の 3月くらいから個人的に PayPal 決済連携の検証をしていたので、今回の Meetup はすごく勉強になりました。特に、PayPal の Okamura Junichi さんに直接疑問をぶつけることができたのが一番の収穫でした。


今回ゲットした情報ですごく有益だったものをいくつかピックアップ。



あと、ドキュメントがとっ散らかっていた印象を受けた 3月頃に比べて、現在は、PayPal の公式ページが徐々にリニューアルされて情報が整理されつつあるようです。

有益な情報源をいくつかゲット。



前回のイベント「PayPal Tech Meetup #1」の存在を知らなかったのですが、知りたかった機能についていくつか紹介されているっぽいです。検証時に知っていればもっと楽だったのになぁ。。



それはそうと、今回の Meetup は豪華賞品付きのデモ大会でした。テーマは「PayPalまたはBraintree APIを使ったアプリ(Web、モバイル、デバイスなど種類は問いません)」で、10人の参加者が LT形式で 5分ずつの枠でプレゼンを行いました。


私は 5番目に発表した @eiden 永田雅文さんの「Botにコーヒーを頼むアプリ」に投票しましたが、結果は二位でした。惜しいっ!!
一位は @kameturu 亀井浩明さんの「暮らしの中のPayPal」でした。
おめでとうございます!!


f:id:akiyoko:20160615212945j:plain



 

1. PayPalボタンで商品を実際に売ってみたよ

@n0bisuke さん(株式会社LIG)

  • サーバ側から push する機能を作ってる
  • Service Worker + WebPush
  • PayPal Button + Notifications API
  • PayPal の Webhook は Https しか対応してない
  • RequestBin を使う
  • netlify
  • SendPulse


 

2. Instagramでお買い物

新井健三さん(Rascal)


 

3. 暮らしの中のPayPal

@kameturu 亀井浩明さん(Origami)


  • ECじゃなくて、Raspberry Pi を使って通常の店舗でスマホを使って PayPal を使う
  • One-Touch を使いたかった。。
  • PayPal REST API (Payments API)
  • Eddystone で飛ばした(iBeacon は将来対応?)


 

4. 専属家政婦くん

@tokutoku393 ちゃんとくさん

  • 何の成果も得られませんでした!


 

5. Botにコーヒーを頼むアプリ

@eiden 永田雅文さん(株式会社Showcase Gig)



 

6. MessangerAPIで課金

@bboobbaa 吉澤和香奈さん(株式会社CAMON.TOKYO)


  • ベトナム人向けに簡単にチケットを売りたい
  • ベトナム人ほとんどFacebook使ってる
  • Messenger でボットを使う


 

7. PayPal APIとAWSで作る動画コンテンツマーケットサイト

@takeyuweb 竹内雄一さん



 

8. テラレン@LINE窓口

@matsubokkuri 松倉友樹さん


  • テラレン
  • PayPal Subscription を使ってる
  • LINE bot で窓口を自動化


 

9. ちょっと寄付休憩はいりまーす

keigohtr 服部圭悟さん(Apitore)

  • 寄付と昼寝
  • PayPal In-Context Checkout


 

10. ブロックチェーンで資産管理

jkkch 菊池条さん


  • デジタルコンテンツの所有権を管理
  • オンラインカードショップの ECサイト
  • ブロックチェーンは Eris を使用

「Vue.js Tokyo v-meetup="#1"」に参加してきました

会場

株式会社プレイド
東京都品川区西五反田1-5-1 五反田サンケイビル 4F


Twitter

twitter.com


感想など

Vue.js は、シンプルなデータバインディング機能(控えめなリアクティブシステム)を持った MVVM フレームワークで、そのシンプルさをウリにしています。

Vue.js (発音は / v j u ː /、view と同様) はインタラクティブな Web インタフェースを構築するためのライブラリです。Vue.js のゴールは、できる限りシンプルな API でリアクティブデータバインディング と 構成可能な View コンポーネントを提供することです。


概要 - vue.js

その他にも、

  • 拡張可能なデータバインディング
  • 純粋な JavaScript オブジェクトモデル
  • 理に適ったシンプルな API
  • コンポーネントで UI をビルド
  • 小さいライブラリとマッチしてミックスできる

といった特徴があるようです。(「公式ドキュメント」より)


私はフロントエンジニアではなくて、少し前に隆盛を極めた AngularJS の 1系や、最近 Webフロントエンド界隈で注目を集めている React.js には全然付いて行けていないので、その対抗馬としてシンプルで学習コストが低いという噂の Vue.js をひと目見てみようと、今回特に何の事前知識もなく敵情視察に来たわけですが、なかなかのアウェー感で歯がゆい想いをしました(笑)。


そもそも Vue.js は 2013年に誕生し、2015年10月に 1.0 がリリースされ、この 4月に 2.0 がアナウンスされています(現在ベータ)。
そして、人気急上昇中の PHP フレームワーク「Laravel」のコミュニティにフロントエンドライブラリとして採用された、というのも興味深いところです。

Taylor Otwell, the author of Laravel, picked up Vue.js instead of React as he was searching for a new front-end library. Soon afterwards Jeffrey Way created a screen cast series on Laracasts which popularized Vue.js in the Laravel community. Today some of the most active Vue.js users are from the Laravel community and there are really cool open source projects like Koel built with the two technologies combined.


Vue.js: 2015 in Review

(参考)
Learning Vue 1.0: Step By Step


話題の JSフレームワークという括りで Vue.js/React.js/Ember.js/Knockout.js を比較したトレンドを見てみると、React.js となかなかいい勝負をしているように見えます。



しかしながら、AngularJS パイセンをキーワード候補に入れた途端、その圧倒的な人気を前にして他のフレームワークがひれ伏すことになります。。

勉強会のあと、公式ドキュメント を読んだりしたところによると、JavaScript 以外のサーバサイドフレームワークとの相性も良さげで、お手軽にデータバインディングを試せそうだなと感じました。


8分で入門 Vue.js

@hashedrock さん


  • 一番使うバインディング機能の説明
  • いろいろ組み合わせが可能
    • Vue.js+SVG
    • Vue.js+Canvas
    • Vue.js+D3.js
  • なぜ Vue.js なのか?
    • デザイナーと開発者のハイブリッド


 

ViewModelのダイエット Messengerパターン編

@kitak さん

Vue.js Tokyo v-meetup="#1"でLTしてきた、と発表からカットしたMVVMのあれこれ - kitak.blog

  • M・V・VMに分割
  • 揮発性の現象
    • ダイアログや画面遷移など(は本来消失すべき)
    • 元々 ViewModel で扱っていた状態や振る舞いが、ダイアログの状態と混ざってしまう
  • VM が Messenger を使ってイベントを発火する
  • $emit で投げて Vue.directive で受け取る



 

Vue, from view to view

@lepture さん

  • component は UI
  • widget はサーバとやり取り


 

翻訳から始めるVue.js入門

@hypermkt さん

  • vue-validator 日本語ドキュメントが昨日リリース
  • JTF日本語標準スタイルガイド(翻訳用)に準拠
  • textlint
    • テキスト向けのLintツール
  • 一部カスタマイズ
  • 翻訳してもVue.jsには詳しくならない。。


 

Vue.js体験記(2ヶ月目)

@sibukixxx さん

  • サーバサイドは Laravel
  • マニュアルではわからなかったことも
  • 0.1系の古いシンタックスのままの記事が多い
  • webpack の存在を忘れていた
    • vue file を component に分けても require できない
  • requirebin の webpack版「WebpackBin
  • awosome-vue にいろいろサンプル集が載ってた


 

SPA with Vuex + Vue-Router

@tejitak さん


  • SPA やるなら他にもいろいろなフレームワークがある
    • Ember は海外で人気、Riot は最近出てきた
  • 何でも SPA にすればいいものでもない
    • 本当にパーシャルレンダリングが必要?
    • SEO 効かないとか
  • Vuex は flux アーキテクチャ、redux と同じ考え方
    • Store, Mutation, Action
  • 双方向バインディングは禁止?
  • 両方使うときに便利なのが、Vue-router-sync



 

Evan You Q&A セッション with Skype

Q. 今後、2.0 の展望は?

  • 疎結合で並列で開発中。vue core はほぼ出来上がってる。ほかはまだ出来上がってないので、2.0 はまだリリースできない
  • スポンサーが出資してくれる人が増えてきたので、個人で会社を立ち上げるらしい。vue.js の未来は明るいよ

 

Q. Vue.js を選ぶ一番の理由は?

  • simple, faster, smaller
  • 学ぶの簡単なので、トレーニングコストが低いのはビジネス面で有利
  • Redux, React はコミュニティが大きい、バックグラウンドがしっかりしている。Vue.js もこれから追いつくよ
  • 技術的なメリットはパフォーマンス。React は大きいプロジェクトではオプティマイズが大変

 

Q. Webworker を使ってパフォーマンス上げる予定ある?

  • 予定はない。60 msec 内に UI をアップデートできているので、今のところ必要性が無い
  • 将来的に実装は可能ではある

 

Q. 2.0 のコードネームは?

  • Ghost in the shell

 

Q. 少ないエンジニアで開発できるモチベーションは?

  • React は大きい会社がバックにいて、いろんな需要が満たされるようにしないといけない。React はニーズに応える必要があるけど、Vue.js は使ってくれるデベロッパーをハッピーにしたい。アイデアが根本的に違う
  • Facebook はリクルーティング目的で OSS にした?

 

Q. AltJS や 特定のビルドシステムを推奨することはある?

  • 直接使わせるようなことはない。実際に裏で使ってる人はいるはず

ゼロからはじめる Django で ECサイト構築(その3:Django Oscar の機能を調べる)

Django 製の ECパッケージの決定版とも言える Django Oscar は、公式ドキュメント によると、以下の 16 個の機能(Django App)から構成されています。
Oscar Core Apps explained — django-oscar 1.3 documentation



機能
概要
備考
Address 住所登録 配送先住所や請求先住所を管理する
Analytics アナリティクス 商品およびユーザーについてのアナリティクスが利用できる
Basket バスケット ショッピングカート機能が利用できる
Catalogue カタログ 商品カテゴリを管理する
Checkout 決済手続き 特定のフローに沿って決済手続きができる
Customer 顧客管理 在庫切れアラートやメール送信など、顧客とのやり取りを行う。他にも、メンバーシップやマイページのほとんどの機能がここに含まれる
Dashboard ダッシュボード 商品カタログ管理、商品注文管理、在庫・出庫管理、オファー管理などのバックオフィス機能のためのダッシュボード。Django admin サイトの代わりとして利用する
Offers オファー 柔軟な条件のディスカウントを設定することができる
Order 商品注文 在庫数のチェックロジック、ディスカウントや配送料を含めた料金計算ロジックを提供する。画面は無い
Partner パートナー 商品の仕入先パートナー(Supplier)を登録したり、在庫・出庫パートナー(Fulfilment Partner)が利用する情報を提供したりする機能。SKU、在庫数、価格などが記録された在庫元帳(Stockrecord)、税率ポリシーや在庫ポリシーを持つストラテジー(Strategy)を管理することもできる。なお、在庫元帳とストラテジーから、商品を購入するのに必要な情報(PurchaseInfo)を取得する
Payment 購入情報 特定の決済代行サービスのための機能を利用することができる
Promotions 広告 広告のためのコンテンツブロックを作成し、特定の位置(トップページ、検索結果ページなど)に表示することができる
Search 商品検索 商品検索機能が利用できる
Shipping 配送料計算 配送先住所やショッピングカートの合計重量、その他いろいろな条件に応じて、自動的に配送料の計算をすることができる(ように設計されている) *1
Voucher バウチャー いろいろなタイプのクーポンコードを設定することができる
Wishlists ウィッシュリスト ほしい物リストが利用できる





今回は、前回 構築した Django Oscar の Sandbox サイトを実際に動かしながら、Django Oscar の機能の一覧を調べていくことにします。


f:id:akiyoko:20160611012326j:plain





 

メンバーシップ

アカウント登録、退会、パスワード変更、ログイン、ログアウトの機能はひと通り揃っています。


 

アカウント登録

メールアドレスをベースにしたアカウント登録をすることができます。基本的なバリデーションはデフォルトで実装されています。

f:id:akiyoko:20160611113759p:plain

退会

少しわかりにくいですが、退会は、プロフィールページ(右上の[Account]>[Profile]で遷移)から[Delete Profile]を押下することでアカウントを削除することができます。

f:id:akiyoko:20160608011151p:plain
f:id:akiyoko:20160608004823p:plain

パスワード変更

パスワード変更もプロフィールページから操作することができます。

f:id:akiyoko:20160608011011p:plain
f:id:akiyoko:20160608071145p:plain

上記の方法とは別に、ログインページからもパスワードの変更(リセット)が可能です。

f:id:akiyoko:20160608004522p:plain

パスワードリセットのためのメールを送信することができます。
f:id:akiyoko:20160608071816p:plain

You're receiving this e-mail because you requested a password reset for your user account at example.com.


Please go to the following page and choose a new password:

http://example.com/en-gb/password-reset/confirm/Mw/4ck-c1f54b78fdaa9e31e057/

メール本文のリンクをクリックすると、パスワード変更ページに遷移します。

f:id:akiyoko:20160608071558p:plain

ログイン

Sandbox では、ログインとアカウント登録は、同一画面で行うように実装されています。

f:id:akiyoko:20160608011309p:plain

ログインせずに、ゲストとして商品を検索したり商品を注文したり *2 することも可能です。

ログアウト

任意でログアウトも可能です。

f:id:akiyoko:20160608072131p:plain

 

マイページ

右上の[Account]からアカウントごとのページ(いわゆるマイページ)に遷移することができ、そこでは以下の機能を利用することができます。


f:id:akiyoko:20160608013201p:plain

プロフィール(Profile)

プロフィールページでは、氏名やメールアドレス、アカウント登録日時を表示できるほか、パスワード変更や退会を行うことができます。

f:id:akiyoko:20160608213427p:plain

注文履歴(Order History)

商品注文の履歴一覧、および詳細を確認することができます。
また、注文履歴の詳細画面から再注文をすることもできます。

f:id:akiyoko:20160609074548p:plain


登録済み住所一覧(Address Book)

登録した住所は、デフォルトの配送先住所(shipping address)、デフォルトの請求先住所(billing address)として設定しておき、商品注文時に再利用することができます。

f:id:akiyoko:20160611165642p:plain

メール一覧(Email History)

システムから送信されるメールの一覧を確認することができます。

f:id:akiyoko:20160610004545p:plain

在庫切れアラート(Product Alerts)

在庫切れになっている商品の詳細画面から[Notify me]ボタンを押下することで、サイト管理者にアラートを通知することができます。
f:id:akiyoko:20160610030515p:plain

マイページの[Product Alerts]から、通知した在庫切れアラートの一覧とそのステータス(サイト管理者が変更する)を確認したり、アラートを自らキャンセルしたりすることができます。
f:id:akiyoko:20160610030538p:plain

再入荷通知(Notifications)

在庫切れアラートに対するサイト管理者からのレスポンスとして、再入荷通知が行われます。
f:id:akiyoko:20160609074655p:plain

ウィッシュリスト(Wish Lists)

商品検索時にウィッシュリスト(ほしい物リスト)に入れていた商品を確認することができます。

リストは複数作成でき、それぞれのリストに名前を付けることができます。

f:id:akiyoko:20160608214516p:plain
f:id:akiyoko:20160608214545p:plain

 

商品紹介

商品紹介機能には、以下のようなサブ機能があります。

 

商品カテゴリ別表示

Sandbox サイト構築時に、ダミーの商品が 200点ほど自動的に登録されます。それぞれの商品にはカテゴリが付けられていて、商品カテゴリ別の一覧表示をすることができます。

f:id:akiyoko:20160608215231p:plain

商品検索

右上の検索窓から、商品のキーワード検索をすることができます。ちなみに、検索のバックエンドはプラガブルに入れ替え可能で、デフォルトで Haystack の各種検索エンジンを利用することができます。

f:id:akiyoko:20160608204907p:plain


商品の並び替え

商品検索をした後、以下の条件で並べ替えをすることができます。

  • キーワードへの関連性(Relevancy)
  • ユーザー評価の高い順(Customer rating)
  • 価格の高い順(Price high to low)
  • 価格の低い順(Price low to high)
  • タイトルの昇順(Title A to Z)
  • タイトルの降順(Title Z to A)

f:id:akiyoko:20160608204132p:plain



レビュー(ユーザー評価)

商品詳細ページで、レビュー(ユーザー評価)を書き込むことができます。
レビューの公開設定は、サイトの設定で承認制にすることも可能です。

f:id:akiyoko:20160608082137p:plain


レコメンド(おすすめ商品)

商品詳細ページの下の方に、おすすめ商品一覧(Recommended items)が表示されます。なお、Sandbox では、おすすめ商品はダッシュボード上でサイト管理者が手動で設定する仕組みになっています。

f:id:akiyoko:20160610103746p:plain


最近チェックした商品一覧

商品詳細ページの下の方に、最近チェックした商品一覧(Recommended items)が自動的に表示されます。

f:id:akiyoko:20160610103851p:plain



商品注文

商品注文としては、次の機能が含まれています。

 

ショッピングカート(Basket)

Amazon での「カート」、楽天市場での「買い物カゴ」と同等の機能が使えます。

商品詳細ページの[Add to basket]ボタンを押下することで、ショッピングカートに商品を追加することができます。

f:id:akiyoko:20160609073056p:plain

右上の[View basket]ボタンから、カートの中身をチェックすることができます。

f:id:akiyoko:20160609073117p:plain

ショッピングカートはこのように表示されます。

f:id:akiyoko:20160609073312p:plain

ショッピングカートの状態(アイテムの中身)は Cookie に保存され、Sandbox のデフォルト設定では一週間保持されることになります。



商品注文(Order)

ショッピングカートの状態に応じて、適切なディスカウントが自動的に適用されます。また、ユーザーに入力されたクーポンコードによるディスカウントについてもここで合わせて計算されます。

f:id:akiyoko:20160609073312p:plain

なお、通常の商品注文だけではなく、プレオーダー(予約注文)やバックオーダー(在庫切れ商品の取り寄せ注文)も可能です。また設定次第で、ゲスト注文(アカウント登録せずに商品注文すること)を許可することもできます。



決済手続き(Checkout)

Oscar の決済手続きは通常、以下のステップに沿って進められます。

1.ゲスト注文不可ならアカウント登録へ(ログイン済みの場合はスキップ)
   ↓
2.配送先入力
   ↓
3.配送方法選択(配送方法が一つのみの場合はスキップ)
   ↓
4.決済方法選択
   ↓
(PayPal ページにリダイレクト)
   ↓
(PayPal 買い手アカウントで認証して、決済内容を承認)
   ↓
5〜7.プレビュー & 決済内容詳細表示 & 注文確定(支払い)
   ↓
8.「ご注文ありがとうございます」

Checkout — django-oscar 1.3 documentation を参考に改編)


商品の決済手続きをする場合は、ショッピングカートページから「決済手続きに進む(Proceed to checkout)」ボタンを押下します。
f:id:akiyoko:20160609073349p:plain

(ログイン済みなので自動的に)配送先入力ステップに進みます。ここではデフォルトの配送先を選択します。
f:id:akiyoko:20160609073426p:plain

配送方法選択ステップはスキップされ、決済方法選択に進みます。
ちなみに今回は、Sandbox 構築時に決済モジュールとして PayPal しか設定していないため、ここでは PayPal 以外の選択肢がありません。
f:id:akiyoko:20160609073446p:plain

PayPal のログインページにリダイレクトされます。ここで PayPal の買い手アカウントでログインして、
f:id:akiyoko:20160609073647p:plain

決済内容を承認すると、
f:id:akiyoko:20160609073709p:plain

ECサイトのプレビューページに戻ってきます(決済はまだ確定していません)。

プレビューページの「注文確定(Place order)」ボタンを押下すると、支払いが完了します。
f:id:akiyoko:20160609073732p:plain

最後に確認ページが表示されます。
f:id:akiyoko:20160609073807p:plain


 

ダッシュボード(Dashboard)

ダッシュボードでは、商品カタログ管理、商品注文管理、在庫・出庫管理、オファー管理などのバックオフィス機能を利用することができます。

ダッシュボードのホーム画面には、指標となるデータがまとめて一覧表示されています。

f:id:akiyoko:20160610022412p:plain


ダッシュボードで利用できる機能としては、主に以下のようなものがあります。


 

商品カタログ管理(Catalogue)

商品カタログ管理機能では、単に商品を登録するだけでなく、様々な付加情報を設定することができます。

商品カテゴリ登録(Categories)

カテゴリとサブカテゴリを親子関係で紐付けることで、ツリー構造の商品カテゴリを実現することができます。Structure には、親カテゴリ、子カテゴリのほか、スタンドアロンの 3種類のいずれかを指定することができます。

なお、商品カテゴリは、主にナビゲーションのためだけに使用されます。


最上位の商品カテゴリは、[Catalogue]>[Categories]から管理します。

f:id:akiyoko:20160609071117p:plain

[Number of child categories]のリンクか、[Actions]>[Edit children]から辿ってサブカテゴリを編集することができます。


商品登録(Products)

[Catalogue]>[Products]で移動できる商品一覧ページから、商品を登録・編集することが可能です。

ちなみに、商品一覧ページには在庫数が表示されておらず、少し不便です。私個人的にはデフォルトで表示させてほしいところです。

f:id:akiyoko:20160609071138p:plain

商品は、事前に作成した「商品タイプ(Product type)」に紐付ける必要があります。


商品を選択後、[Stock and pricing]タブから仕入先パートナーや在庫数、通貨、価格を設定したり、[Upselling]タブからレコメンド(おすすめ商品)を設定したりすることができます。

f:id:akiyoko:20160611142403p:plain
f:id:akiyoko:20160610030319p:plain


 

在庫・出庫管理(Fulfilment)

在庫・出庫のために必要な情報を提供します。

商品注文管理(Orders)

[Fulfilment]>[Orders]から、商品注文の一覧を確認することができます。

ユーザー側で決済まで完了した商品注文は「Pending」ステータスになっているため、例えば、出庫の受付が済んだら「Being processed」に、配送が完了したら「Complete」に、というふうにステータスを切り替えることができます(手動で切り替えます)。
f:id:akiyoko:20160609081752p:plain

パートナー登録(Partners)

[Fulfilment]>[Partners]から、パートナーを作成したりパートナー一覧を確認したりすることができます。

パートナーには、ユーザーを任意で紐付けることができます。
f:id:akiyoko:20160609081831p:plain

顧客管理(Customers)

ユーザー管理(Customers)

[Customers]>[Customers]から、ユーザーごとの注文履歴や登録済みの住所、商品レビューの一覧などの情報を確認できるほか、パスワードリセットのためのメールを送信するボタンも用意されています。
f:id:akiyoko:20160609082251p:plain


在庫切れアラート管理(Stock alert requests)

[Customers]>[Stock alert requests]から、ユーザーからリクエストされた在庫切れアラートの一覧を確認することができます。
f:id:akiyoko:20160610031030p:plain


オファー管理(Offers)

オファー管理では、ディスカウントとバウチャーの管理をすることができます。

 

ディスカウント登録(Offers)

[Offers]>[Offers]から、ディスカウントを登録・編集できます。
f:id:akiyoko:20160609071005p:plain

Sandbox にデフォルトで登録されている以下の三種類のディスカウントのほか、ボリュームディスカウントなど柔軟な条件のディスカウントを設定することができます。

  • 1)規定個数以上買えば 1つ無料
    • ショッピングカートに 規定個数以上の商品を入れれば、その中で最も価格が安い商品が 1つ無料になるというタイプのディスカウントです。デフォルトの「Normal site offer」は、3個以上で 1つ無料という設定になっています。
  • 2)購入後特典(deferred benefit)
    • 購入後にポイントがもらえる的なディスカウントも設定可能です。Sandbox の「Deferred benefit offer」の説明には「商品を買ったら名前が Barry になるよ」というのが書かれているのですが、イギリスのギャグ(?)なのでしょうか。。(ちなみに、本当に購入後にユーザー名が Barry になってしまいます 笑)
  • 3)配送料無料

f:id:akiyoko:20160609071038p:plain


クーポンコード登録(Vouchers)

[Offers]>[Vouchers]から、クーポンコードを登録・編集することができます。ディスカウントは条件に応じて自動的に適用されるのに対し、クーポンコードは、ユーザーがコードを適宜入力する必要があります。


クーポンコードの登録にあたってはいろいろ柔軟な指定ができるようになっていて、例えば、それぞれのクーポンコードの使用制限について、以下の中から選択することができます。

  • 誰でも一回だけ使用可
  • 誰でも何回でも使用可
  • 先着一名のみ一回だけ使用可

また、割引きの種類については以下の中から選択可能です。

  • パーセント指定で割引
  • 金額指定で割引
  • 配送料のパーセント指定で割引
  • 配送料の金額指定で割引
  • 配送料が固定金額に

f:id:akiyoko:20160609071209p:plain
f:id:akiyoko:20160609071242p:plain


コンテンツ管理(Content)

アバウトページなどの固定ページを編集できるほか、[Content]>[Reviews]からユーザーレビューを確認することもできます。

f:id:akiyoko:20160609082027p:plain



レポート出力(Reports)

レポート出力機能では、様々なレポートを出力することができます。

f:id:akiyoko:20160611151345p:plain


決済状況管理(PayPal)

こちらは決済モジュールに django-paypal を利用した場合に使えるようになる機能ですが、[PayPal]>[Express transactions]から、ユーザーが PayPal 決済のトランザクションで使用した決済API のレスポンスの一覧および詳細を確認することができます。

これにより、決済処理中のエラーをトラッキングして解決に役立てることができるようになります。

f:id:akiyoko:20160609082133p:plain
f:id:akiyoko:20160609082200p:plain



 

まとめ

もちろん今回調査した機能以外にも、様々な機能が Django Oscar にはデフォルトで備わっています。しかしながら、今回の調査結果で分かるように、Django Oscar には、ECサイトを運営する上で必要となる基本機能はだいたい揃っていると考えてよいでしょう。


あとは、日本で Django Oscar を利用して ECサイトを構築したときに、日本の商習慣に合わせたカスタマイズ、ローカライズが必要になってくると考えられます。そこは追々やっていくとして、今後は、Oscar の機能をもう少し深追いしてみたいと思います。

*1:How to configure shipping — django-oscar 1.3 documentation

*2:ゲスト注文を許容するかどうかは設定次第

ゼロからはじめる Django で ECサイト構築(その2:Django Oscar の Sandbox サイト構築)

前回の記事「ゼロからはじめる Django で ECサイト構築(その1:ECパッケージの選定)」では、Django ベースの ECパッケージを選定し、「Django Oscar」が圧倒的人気で最有力候補であることが確認できました。


<過去記事>
akiyoko.hatenablog.jp


今回、「ゼロからはじめる Django で ECサイト構築」シリーズの第二回では、実際に、Django Oscar の Sandbox サイトを構築していくことにします。



f:id:akiyoko:20160531080056j:plain




 

Django Oscar について

概要

Django Oscar は、ECサイトを構築・運営するために必要な多くの機能が盛り込まれた、オープンソースで Django 製の ECパッケージです。ライセンスは修正BSDライセンス(New BSD license)で、商用利用も可能です。

github.com


機能の詳細については、次回以降にまとめていく予定です。


Sandbox とは

Sandbox とは、動作確認をするための開発者用のテスト環境のことを指します。
いわゆる「デモ環境」のことですね。

Django Oscar には、いろんな機能が組み込まれたデモサイトを簡単に立ち上げられるような仕組みが備わっていて、これを使うことで、Django Oscar の機能をお試しで検証することができます。




 

ECサイト構築に必要な三要素

さて、ECサイトを構築するためには、

  • 決済代行サービスのマーチャントアカウント
  • ECパッケージ
  • サーバ

の三つが必要最低限の要素として挙げられるでしょう。


まず一つ目の「決済代行サービスのマーチャントアカウント」は、PayPalWebPay などの決済代行サービスのビジネスアカウント(売り手アカウント)を指します。Sandbox 環境においては、Sandbox(ややこしいですが、決済代行サービス側が用意してくれるテスト環境を指します)用のマーチャントアカウントを使用することで、実際に支払いをすることなく決済処理の流れをシミュレートすることができます。


今回の検証では、決済代行サービスとして PayPal を利用するのですが、Sandbox については次のように説明されています。

ペイパルでは、決済サービスの動作確認ができるテスト環境として、Sandboxを公開しています。
テスト用の「Buyer(買い手)」アカウントと、「Seller(売り手)」アカウントを作成し、サービスの導入から、決済の流れまで、詳細にシミュレーションすることができます。


Sandbox | ペイパルビジネスガイド - PayPal


二つ目の 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.1. 最低限のライブラリをインストール
$ sudo apt-get update
$ sudo apt-get -y install python-dev git tree

 

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)


参考


 

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 +0200

Merge 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/
にブラウザからアクセスします。

f:id:akiyoko:20160529121316p:plain


ログインユーザ

username: superuser
email: superuser@example.com
password: testing

username: staff
email: staff@example.com
password: testing

f:id:akiyoko:20160529121332p:plain

f:id:akiyoko:20160529121348p:plain


疎通ができたら、Runserver を一旦停止します。


ちなみにここまでの設定では、決済モジュールの設定をしていないので、決済処理を完了することができなくなっています。

f:id:akiyoko:20160529122316p:plain

(住所や電話番号などのダミー情報は、US Address Generator - Fake Address, Random Address Generator で生成したものを入力しました。)
f:id:akiyoko:20160529122334p:plain

f:id:akiyoko:20160529122349p:plain

このように、決済モジュール(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」のチェックを外します。

f:id:akiyoko:20160529125100p:plain

要するに、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」を選択することにします。


手順は以下の通りです。


参考
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/
f:id:akiyoko:20160531003041p:plain

Sandbox アカウントではなく、通常の PayPal アカウントでログインします。
f:id:akiyoko:20160531003105p:plain

「DASHBOARD」をクリックします。
f:id:akiyoko:20160531003128p:plain

「Accounts」を選択します。
f:id:akiyoko:20160531003200p:plain

Sandbox 用の「Buyer アカウント(マーチャントアカウント)」と「Seller アカウント(買い手アカウント)」がデフォルトで用意されている(はずな)ので、Type が「BUSINESS」となっている方の Buyer アカウントの「Profile」をクリックします。
f:id:akiyoko:20160531003227p:plain

「API Credentials」タブから Test API Credentials を確認することができます。
f:id:akiyoko:20160531003251p:plain


参考(PayPal 公式)


参考(Test API Credentials)


参考(ビジネスアカウント)


 

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 のソースコードのままでは、以下のようにエラーが出てしまいます。

f:id:akiyoko:20160529145830p:plain

テンプレート内で、

{% 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 %}

上記の対応後、ショッピングカート画面を確認すると、以下のように表示が少し崩れてしまっています。

f:id:akiyoko:20160529150928p:plain


こちらは、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 %}

これで、きちんと表示されるようになりました。
f:id:akiyoko:20160529151517p:plain


 

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

こちらも、同様のエラーが出るので、
f:id:akiyoko:20160529152118p:plain


以下のように修正を加えます。

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>&nbsp;</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>&nbsp;</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 %}

f:id:akiyoko:20160529152616p:plain

ここでは詳しく触れませんが、日本では「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>&nbsp;</div>
    </div>
{% endblock %}

f:id:akiyoko:20160529152636p:plain



 

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 %}#}
    ・
    ・


f:id:akiyoko:20160529154701p:plain


sites/sandbox/templates/paypal/express/dashboard/transaction_detail.html

{% extends 'dashboard/layout.html' %}
{% load currency_filters %}
{% load i18n %}
{#{% load url from future %}#}
    ・
    ・

f:id:akiyoko:20160529154718p:plain


以上で、Django Oscar の Sandbox サイトを構築するまでの作業は終了です。



GitHub にも修正内容をアップしたので、こちらも参照してください。
GitHub - akiyoko/oscar_sandbox




 

まとめ

やや細かな修正内容まで言及してしまいましたが、Django Oscar の Sandbox サイトを構築して、決済モジュールを導入するまでの手順を紹介しました。

これで、Django Oscar のいろいろな機能を試すことができるようになりました。次回は、この Sandbox サイトを使って、Django Oscar の ECサイトとしての機能を検証していきます。