akiyoko blog

akiyoko の IT技術系ブログです

ゼロからはじめる Django で ECサイト構築(その1:ECパッケージの選定)

はじめに

とあるニーズがあって、Python(ほぼ Django 一択)ベースの ECパッケージを使った ECサイトを構築しようかと、昨年の10月頃から細々と調査をしていたのですが、EC-CUBE や osCommerce、Zen Cart、Magento、WordPress + WelCart など PHPベースの ECパッケージについて書かれた記事は数多く存在するのですが、Pythonベースの ECパッケージについての記事があまり無いように思ったので、勉強がてらメモを残していきたいと思います。




 

ECサイトのタイプ

まず第一に、ECサイトには、以下に示したような構築方式および出店方式の違いがありますが、導入実績や信頼性、初期・月額費用、構築期間、カスタマイズ性、専門知識の必要性、集客・販促の必要性などの特徴を考慮しつつ、目的に合ったものを採用する必要があります。

以下の表では、構築・出店方式のタイプ別に、構築や運用の手間がかかりそうな順に並べてみました。

構築・出店方式 概要 代表例
フルスクラッチ型 フルスクラッチで構築
無料パッケージ型 オープンソースの ECパッケージをサーバに導入 EC-CUBEZen CartLive Commerce など
有料パッケージ型 有料の ECパッケージをサーバに導入 ecbeingコマース21 など
ASP型 ECサービスをレンタル えびすマートエレコマ など
インスタントEC型 簡単にネットショップ開設 Stores.jpBASE など
オンラインモール型 Web上の仮想商店街 楽天市場、Amazon、ポンパレモール など
C2Cモール型 消費者間取引 ヤフオク、メルカリLINE MALL など






参考



私の場合は、カスタマイズ性と構築費用(ECパッケージのコストゼロ)を最優先させかったので、オープンソースの ECパッケージを利用する「無料パッケージ型」を採用することとしました。



 

ECパッケージの特徴

そもそも ECパッケージとは、ECサイト(電子商取引をするためのネットショップ)を構築するために必要な数々の機能を一つにまとめたソフトウェアを指します。


一般に、ECパッケージに求められる機能としては、

  • ショップフロント機能
    • 商品紹介
      • 商品カテゴリ別表示
      • 商品一覧
      • 商品詳細
      • 商品検索(キーワード / 価格帯)
      • 商品の並び替え(注文数 / 価格 / 新着 / ユーザー評価)
      • 最近閲覧した商品紹介
      • ユーザー評価(レビュー)
    • 商品注文
      • ショッピングカート
      • 決済手続き
        • クレジットカード決済
        • 振込決済(コンビニ / 銀行 / 郵便局)
        • 代引決済
        • 携帯キャリア決済
      • タイムセール
      • クーポン
      • ディスカウント(ボリュームディスカウント / 配送料無料)
      • ゲスト注文
      • 予約注文
      • 関連商品・レコメンド(この商品を買った人はこんな商品も買っています)
    • メンバーシップ
      • アカウント登録
      • 退会
      • パスワード変更
      • ログイン
      • ログアウト
    • マイページ
      • 注文履歴
      • 配送先登録
      • お気に入り登録(ほしい物リスト)
    • 問い合わせ
  • バックオフィス機能
    • 商品管理
      • 商品カテゴリ登録
      • 商品登録
      • タイムセール登録
      • クーポン登録
      • ディスカウント条件設定
    • 受注管理
      • 消し込み(返品処理)
    • 顧客管理
    • 問い合わせ管理
    • 売上集計
    • 販売分析
    • 各種メール送信
    • システム設定
      • システムメンテナンス
      • デザインテーマ設定
      • 多言語化

などが挙げられます。


無料パッケージにせよ有料パッケージにせよ、ECパッケージの選定においては、上記の機能がどれだけ実現できるかが一つの重要な選定基準となります。




 

ECパッケージの選定

ここで、ECパッケージを選定するために、Djangoベースの ECパッケージの中から人気のあるものをリストアップしてみます。


Djangoベースのパッケージの評価するには、Django Packages : E-Commerce を参照するのが手っ取り早いです。

Django Packages で比較

スター数の上位 4つをリストアップしてみました。
(「SATCHLESS」は最近開発が活発でなくなって来ているようなので、除外しました。)


PACKAGE DJANGO-OSCAR DJANGO SHOP SALEOR CARTRIDGE
Description Domain-driven e-commerce for Django A Django based shop system An e-commerce storefront for Python and Django Ecommerce for Mezzanine
Category Framework Framework Framework App
Development Status Production/Stable Unknown n/a Beta
Last updated April 3, 2016, 5:30 a.m. May 16, 2016, 9:40 a.m. May 11, 2016, 10:38 a.m. April 4, 2016, 2:54 a.m.
Version 1.2rc1 0.9.1 n/a 0.11.0
Stars 1997 1044 501 464
Repo Forks 814 438 199 222
Payment Methods Gateways: DataCash, PayPal, PaymentExpress. There is also an accounts extension that provides support for giftcards, loyalty schemes and customer budgets. cash-on-delivery paypal (ext), postfinance (ext) Easily extensible All supported by django-payments: Authorize.net, Braintree, Coinbase, Cybersource, Dotpay, Google Wallet, PayPal, Sage Pay, Sofort, Stripe Authorize.net, eGate, PayPal, Stripe, Braintree, PIN
Shipping options Extremely flexible. Any part of the shipping calculation can be customised to suit your domain. Flat rate, easy api for extensibility Per-country shipping rules provided out of the box, custom options are easy to implement. Split deliveries for a single order Flat rate provided plus hooks for implementing your own rules
Configurable Checkout Steps Yes - The checkout can be easily customised to add, remove, alter or combine steps. It's not controlled by a single setting though. Saleor is meant to be forked so you can just edit the code

Django Packages : E-Commerce より抜粋。2016年5月22日時点のもの)


DJANGO-OSCAR」と「DJANGO SHOP」が二大人気となっているようですが、「DJANGO-OSCAR」のスター数・フォーク数はほぼダブルスコアになっています。

なお、CARTRIDGE のカテゴリが「App」となっていますが、このパッケージはショッピングカート機能のみを提供するもので、「Mezzanine」という CMSパッケージ向けに作られています。


ちなみに、「Django Packages : E-Commerce」の全パッケージ中でステータスが「Production/Stable」になっていたのは、

の 4つだったのですが、スターやフォーク数では「DJANGO-OSCAR」が圧倒的人気です。




ECパッケージの機能の中でも特に重要な機能の一つが「決済処理」ですが、多くの ECパッケージが、Pluggable なモジュール形式の「決済モジュール」を提供しています。PayPal や Stripe などの決済代行サービスに合わせた決済モジュールが個別に用意されているケースが多いのですが、ECパッケージ本体に組み込まれている場合や、別パッケージとしてソースコードが管理されている場合もあります。



 

決済モジュールの特徴

決済処理に特化したモジュールは「決済モジュール」と呼ばれ、Pluggable に差し替え可能な仕組みになっている場合が多く、決済代行サービスに合わせたものをチョイスして取り込むことができます。ECパッケージ本体やサードパーティ(コミュニティ)の決済モジュールで対応できない決済代行サービスを利用したい場合は、決済モジュール自体を自作する必要も出てきます。

決済処理の仕組み

ECサイトの決済処理の仕組みを簡単に図解すると、以下のようになります。

f:id:akiyoko:20160515172525p:plain
10 Safe and Popular Gateways for Online Payment Processing | InstantShift を参考に作成)


ECサイトから見れば、決済代行サービスを窓口(ゲートウェイ)として利用することで、Visa や MasterCard のようなカード会社と直接やり取りすることなしに、決済処理ができるようになっています。


決済モジュールは以下の位置に配置され、API を通じて決済代行サービスとやり取りを行います。

f:id:akiyoko:20160522231309p:plain



決済モジュールは、ECパッケージのチェックアウト機能に合わせた決済モジュールが複数用意されている場合が多いので、使用する決済代行サービスに合わせてチョイスするのがベストです。


例えば、ECパッケージに「DJANGO-OSCAR」を使うのであれば、

django-oscar-datacash Integration with the DataCash payment gateway
django-oscar-paypal Integration with PayPal. This currently supports both Express Checkout and PayFlow Pro.
django-oscar-paymentexpress Integration with the Payment Express payment gateway
django-oscar-accounts Managed accounts (can be used for giftcard functionality and loyalty schemes)
django-oscar-stores Physical stores integration (opening hours, store locator etc)
django-oscar-eway Integration with the eWay payment gateway.
django-oscar-sagepay-direct Integration with "DIRECT" part of Sagepay's API

https://github.com/django-oscar/django-oscar#extensions より)

が本家(django-oscar)から提供されており、これらは比較的信頼性も高いものと推測されます。その他にも、コミュニティが製作した決済モジュールも多々用意されているようですが、こちらの信頼性については個別に検証が必要です。


 
以上から、例えば、決済代行サービスに PayPal を利用する予定であれば「django-oscar-paypal」をまずは検討するのがよい、ということになります。しかしながら、PayPal を利用するにしても、使用する API の種類によっては(例えば日本国内では)対応できないという可能性もあるため、実際に検証が必要となります。



 

決済モジュールの選定

ECパッケージに依存しない決済モジュールも存在します。ECパッケージで用意された決済モジュールが決済代行サービスに対応していない場合などは、それらを使用すれば(カスタマイズは必要になると思いますが)、イチから自作しなくてもよくなるケースもあるでしょう。


こちらについても、Django Packages で比較検討してみることにしました。

Django Packages で比較

スター数の上位 5つをリストアップしました。
(「LFS - LIGHTNING FAST SHOP」は ECパッケージなので除外。加えて、「DJANGO-ZEBRA」は長年メンテされていなさそうなので除外しました。)


PACKAGE DJANGO-MERCHANT DJANGO-PAYPAL DJ-STRIPE DJANGO-GETPAID DJANGO-PAYMENTS
Description A Django app to accept payments from various payment processors via Pluggable backends. A pluggable Django application for integrating PayPal Payments Standard or Payments Pro Django + Stripe Made Easy Django payments processor. Universal payment handling for Django
Development Status Alpha Unknown Beta Production/Stable n/a
Last updated July 8, 2015, 1:29 a.m. May 9, 2016, 1:51 p.m. May 11, 2016, 12:01 p.m. Jan. 25, 2016, 4:58 p.m. April 20, 2016, 12:05 p.m.
Version 0.2 0.3.2 0.8.0 1.7.3 n/a
Stars 825 307 285 167 142
Repo Forks 142 83 141 63 57

Django Packages : Payment Processing より抜粋。2016年5月22日時点)


全体的に「Production/Stable」ステータスのものが少ない印象です。
また、Stripe や Braintree など、日本ではまだ使えない決済サービス向けに作られたものが多いようにも思いました。



 

まとめ

「ゼロからはじめる Django で ECサイト構築」の第一回として、ECパッケージの選定を行いました。

「DJANGO-OSCAR」が圧倒的人気で機能も充実しているようです。まずは、「DJANGO-OSCAR」の機能を実際に見ていきたいと思います。
また、Mezzanine 向けのショッピングカート機能を提供する「CARTRIDGE」も気になるところです。

今後は、この二つを中心に調査を続けていきます。

Amazon プライムの戦略にまんまとハマってしまった(いい意味で)

昨年 Amazon プライムの会員になってから、早や 9ヶ月ほど経とうとしていますが、今やもう Amazon プライム無しでは考えられないくらいその利便性を痛感しています。

「Amazon プライムの戦略にまんまとハマってしまった」と言っていいかもしれません。
もちろんいい意味で、ですよ。

買ったもの

まず、Amazon プライム会員になってから買ったものを紹介していきます。

Kindle paperwhite おすすめ度:★★★

最初に買ったのは、Kindle端末(電子書籍リーダー)です。

今や通勤時の必須アイテムです。重さが約 200g と軽くて片手で楽に持てますし、バッテリーも数週間もつので大変重宝しています。


キャンペーン情報付きモデルだと通常モデルよりも 2,000円ほど安いのですが、はっきり言ってキャンペーン情報付きモデルの方が絶対お得です。 端末をオンにしたときに、以下のようにキャンペーン情報が表示されるだけで、他には違いはありません。

f:id:akiyoko:20150803012658j:plain



【追記】5/22まで、クーポンコード『PAPERW7300』で Kindle paperwhite が7,300円オフになるキャンペーンをしています。これはお得です。詳細はこちら。
www.amazon.co.jp



Kindle本たくさん おすすめ度:★★★

この一年で本 40冊(漫画除く)、雑誌 30冊ほど買っていました。
Amazon.co.jp: Kindle日替わりセール: Kindleストア」や「Amazon.co.jp: Kindle月替わりセール: Kindleストア」で安くなっているとついつい買ってしまいます。


私は Twitter で @AmazonJPKindle をフォローしているのですが、日替わりセール本を毎日定期的につぶやいてくれるので便利です。


買っただけで読んでいない本がたくさん溜まっているのですが、電子書籍なので、物理的な置き場所を取らないのもいいですよね!



あと、Kindle は頻繁にキャンペーンをやっていて、雑誌 99円セールとか KADOKAWA本半額セールとか、かなりお得なセールを期間限定でやっていたりするので、そういう情報収集も結構大事です。



Fire TV Stick おすすめ度:★★★

Fire TV Stick

Fire TV Stick

これは革命でした。

これで、我が家のテレビ(無駄に 50インチあります)で大画面で Amazon ビデオの映画やドラマ、YouTube を観ることができます。
後で説明しますが、対象となるビデオは限られますが、プライム会員の特典で無料でビデオが見放題になるので、プライム会員との合わせ技は最強です。


YouTube が大きな画面で見れるのも画期的でした。たまに遊びに来る姪っ子の機嫌が悪かったときに、テレビでアンパンマンを見せると元気になったりして、何かと役立ってます。


音声認識リモコンが付いて 1,500円ほど高い「Fire TV Stick 音声認識リモコン付属」というのもありますが、Fire TV のスマホアプリを使えば音声入力もできるので、特に必要ではありません。


Fire タブレット おすすめ度:★☆☆

最近買ったのが、これ。

Fire タブレット 8GB、ブラック

Fire タブレット 8GB、ブラック

Amazon プライム会員の期間限定キャンペーンで 5,000円オフの 3,980円だったので、思わず買ってしまいました。

通勤中にプライム・ビデオを観るのに使っています。スマホよりも大きな 7インチの画面でビデオを鑑賞することができ、画質も非常に綺麗で、とてもいい感じです。


私はモバイルルータを持っていないのですが、Amazonビデオ アプリを使えばタブレットにビデオを Wifi 環境下で事前にダウンロードしておけるので、通勤中でもビデオを観ることができるのです。

ストレージは 8 GB で、microSD を増設できるので容量の心配はありませんが、ビデオは一本あたり 300 MB 〜 1 GB 程度で観終わったらすぐに削除しているため、今のところ外部ストレージは使っていません。



Amazon プライム会員とは何か?

Amazon プライム会員になったのが私の Amazon プライム・ライフの全ての始まりでしたが(いい意味で)、そもそも、Amazon プライム会員とは何でしょうか?


<過去記事>
akiyoko.hatenablog.jp



Amazon プライム会員は年会費 3,900円(税込)の有料サービスなのですが、そのメリットが月額換算 325円とは思えないくらい充実しています。



ほかにもいろいろメリットはあるのですが、私の中で大きなものは次の五つです。

  • メリット①:「当日お届け便」などの Amazon プライム配送が無料
  • メリット②:Kindle端末で月一冊無料で読める(Kindleオーナー ライブラリー)
  • メリット③:Prime Music、プライムラジオが無料で聴き放題
  • メリット④:Amazon プライム・ビデオが無料で見放題
  • メリット⑤:会員限定の割引セール

 

メリット①:「当日お届け便」などの Amazon プライム配送が無料

これは本当に便利です。実際、これで助かったというのがすでに何度もあります。仕事などで緊急に必要になった雑貨や本を即日配送してもらえるという「奥の手」があるというのは、精神的にもすごく楽です。


メリット②:Kindle端末で月一冊無料で読める(Kindleオーナー ライブラリー)

Kindle端末(電子書籍リーダー)限定ですが、Kindleオーナー ライブラリー対象本を月一冊、無料で読むことができます。

これは当初思っていたよりもお得感は少なかったです。
というのも、Kindleオーナー ライブラリーの対象本が思ったよりも全然少なくて、ベストセラーの本とか本当に読みたい本はあまり無く、怪しい(?)自費出版の本が多くて、これだけで年会費を浮かそうというのは(付けられた値段でなくて本の本当の価値を考えると)難しいようにも思います。

しかしながら、たまに Kindleストアの Amazonプライム対象商品の一覧を眺めていると、ちょっと読んでみたい本に出会えるのでなかなか侮れません。

www.amazon.co.jp


メリット③:Prime Music、プライムラジオが無料で聴き放題

これも期待ほどでは無かったのですが、あると無いとでは全然違いますし、実際に結構な頻度で使ってます。

Amazon Music アプリをスマホと Mac にインストールして、今まであまり聴かなかった洋楽を中心に聴いています(邦楽はあまり充実していませんのであまり期待しない方がいいかもしれません)。プライム対象のラインナップはまだまだ少ないので、仕事中のバックグラウンドとして使う目的で考えるとちょうどよさそうです。


あと最近、今年4月から使えるようになった新サービス「プライムラジオ」ですが、これも仕事中のバックグラウンドとして使えそうな感じです。プライム対象のものがランダムで流れているだけなのですが。。

メリット④:Amazon プライム・ビデオが無料で見放題

f:id:akiyoko:20160516075733p:plain

これはスゴイ!

先述の Fire TV Stick と組み合わせることで、その真価が発揮されます。是非、Fire TV Stick の購入をおすすめします。

Fire タブレット 8GB、ブラック

Fire タブレット 8GB、ブラック

対象商品は限られますが、無料で Amazon ビデオが見放題になる特典です。ラインナップはまだまだ少ないですが、若干ながらも日々プライム対象のビデオは増えているようです。

英語の勉強と称して洋画を観始めたのですが、かなりハマってます。コンスタントに週に 2〜3本は観ているという感じです。画質も非常によくて満足しています。

この特典で、確実に 3,900円の年会費の元は取れていると思います。


メリット⑤:会員限定の割引セール

Kindle端末が 4,000〜7,300円オフセールで買えたり、Fire タブレットが 5,000円オフセールで買えたりするので、これだけで Amazonプライム会員の年会費が賄えると考えると、会員にならない理由はありません。


【追記】5/22まで、クーポンコード『PAPERW7300』で Kindle paperwhite が7,300円オフになるキャンペーンをしています。これはお得です。詳細はこちら。
www.amazon.co.jp



まとめ

Amazon プライム会員のメリットは、タイムセールにフライングで参加できたりとか、Amazon パントリーという食品・日用品のディスカウント購入ができたりとか、他にもあるのですが、そちらは利用してないのでメリットはよく分かりません。

しかしながら現状でも、Amazon プライム会員のメリットにとても満足しています。

ということで、Amazon プライムは世界一ぃぃぃぃぃ!

「スマートPythonプログラミング: Pythonのより良い書き方を学ぶ」を読んだ

Amazonプライム会員の特典で月一冊無料で読めるプライム対象本(正確には「Kindleオーナー ライブラリー」の対象本)を眺めていたら、新しい Python 本が見つかったので、早速読んでみました。

著者が想定する読者像は「不安を覚えながらなんとなく動くように Python を書いている人」と書いていますが、全部読んでみた感じでは私は、まず初学者向け Python 本をざっと読み終えた後、何ヶ月か(あるいは一年ほど)Python のコードを実務で書いた上で、「脱初心者」を目指そうとしている Python プログラマを対象としているのかなと思いました。

ということで、初学者向けには少し難しいけど、少し Python をかじった人には知りたいような内容が詰まっています。


例えば、「内包表記(リスト内包・集合内包・辞書内包)」や「ジェネレータ式」、「デコレータ」「コンテキストマネージャ」などは、分かりやすくまとまった記事を見つけるのが難しいように思います。そういった意味でも、なかなか貴重な学習本ではないかと思います。特に、デコレータは、脱初心者が抑えておきたい重要な要素だと個人的に思ってます。

ジェネレータは、あまり頻繁に出てくるものではありませんが、たまに出てくると「あれ?」と考えてしまったりします。ジェネレータは、yield 文で値が返されたときの状態を保持していて、次に呼び出されたときに前回の yield 文の直後から再開されるという、説明だけ聞くとややこしい概念なのですが、この本の説明で「なるほど」と思ったのは、「ジェネレータを呼び出すと、それで得られるのはイテレータオブジェクト」ということで、以下のようなサンプルコード(少し手を入れました)を例示しています。

test.py

#!/user/bin/env python
# -*- coding: utf-8 -*-


def test():
    yield 1
    yield 2
    yield 3


def main():
    it = test()
    for i in it:
        print(i)


if __name__ == '__main__':
    main()

Python 2.7 で実行

$ python test.py
1
2
3


またこの本は、全体的にすごく丁寧に説明されているな、と感じます。
例えば、序章の中で、「Hello, World!」を書くサンプルコードを出していますが、「なぜそう書くのか」を丁寧にひとつずつ解き明かして説明しています。
この部分と第二章の「開発環境を整えよう」は、初学者にも有益で分かりやすい説明になっていると思います。

しかしながら後半、特に、Python のバージョン 2.x 系と 3.x 系を共存させるための書き方などは、初学者や初級者には(頭の片隅には入れておいてもいいですが)めったに出会うこともがないため、最後まで読み切る必要はないと思います。


ともあれ、初学者が、「やさしいPython入門」や「Pythonスタートブック」などの薄めの本を読んだ後の二冊目の教科書として読むのは少し厳しい感じがするので、厚めの本を読んでからこの本を読むのがいいかもしれません。


私の場合は、初めてのときに

を読んだ後、次に、

を部分的に読んで、

を最近読みました。

最後の一冊は Python の言語としての使い方の説明は少ないので、Python 自体の学習という趣旨から外れるかもしれませんね。

NumPy, SciPy を利用するために Python 2系の Anaconda を、pyenv を使ってインストールする

はじめに

Anaconda (アナコンダ) とは


Anaconda は、Continuum Analytics 社によって提供されている、Python 本体に加え、科学技術、数学、エンジニアリング、データ分析など、よく利用される Python パッケージ(2016 年 2 月時点で 400 以上)を一括でインストール可能にしたパッケージです。面倒なセットアップ作業が効率よく行えるため、Python 開発者の間で広く利用されています。なお、Anaconda は商用目的にも利用可能です。



Anaconda を利用した Python のインストール (Windows) – Python でデータサイエンス より


 
以前(3年ほど前)、Mac に NumPy, SciPy をインストールするのにかなり苦労した憶えがあるのですが、最近は、Anaconda というパッケージを使えば、Mac だろうが Windows だろうが、NumPy, SciPy を含む科学技術計算パッケージと Python 本体をまとめてインストールすることができます。データサイエンス界隈では、Anaconda を使って手っ取り早く Python の科学技術計算環境を構築することが多くなっているようです。

<過去記事>
akiyoko.hatenablog.jp


実際にやってみたら、「以前の苦労は何だったのか」と呆気にとられるほど簡単にインストールできたので、メモを残しておきます。また今回、pyenv という Python のバージョンマネージャを使ってみたので、そちらも合わせて書いておきたいと思います。


現状

  • OS X 10.10.5
$ which python
/usr/local/bin/python

$ python --version
Python 2.7.10


これらの環境構築は、Homebrew を使って以下の手順で行っていました。

<過去記事>
akiyoko.hatenablog.jp



 

pyenv

Homebrew で pyenv をインストールします。

$ brew install pyenv

$ pyenv --version
pyenv 20160303

$ cat << EOF >> ~/.bash_profile
export PYENV_ROOT=\${HOME}/.pyenv
export PATH=\${PYENV_ROOT}/bin:\$PATH
eval "\$(pyenv init -)"
EOF

$ source ~/.bash_profile


 

Anaconda

pyenv でインストールできる Python のバージョンを確認。

$ pyenv install -l
Available versions:
  ・
  ・
  2.7
  2.7.1
  2.7.2
  2.7.3
  2.7.4
  2.7.5
  2.7.6
  2.7.7
  2.7.8
  2.7.9
  2.7.10
  2.7.11
  ・
  ・
  3.4.0
  3.4-dev
  3.4.1
  3.4.2
  3.4.3
  3.4.4
  3.5.0
  3.5-dev
  3.5.1
  ・
  ・
  anaconda-2.4.0
  ・
  ・
  anaconda3-2.5.0

Python 2系の Anaconda をインストールします。

$ pyenv install anaconda-2.4.0


インストールした Python を global に適用します。

$ pyenv global anaconda-2.4.0
$ pyenv rehash


バージョン確認。

$ pyenv versions
  system
* anaconda-2.4.0 (set by /Users/akiyoko/.pyenv/version)

$ python --version
Python 2.7.10 :: Anaconda 2.4.0 (x86_64)

$ which python
/Users/akiyoko/.pyenv/shims/python


 

「The Payoneer Forum Tokyo - 越境 EC セミナー」に参加しました

主催

Payoneer Inc.

会場

東京都新宿区西新宿8-17-3 住友不動産新宿グランドタワー 1F
ベルサール新宿グランド




 

Payoneer サービス紹介

ナボン 恵子 氏(Payoneer Inc)

  • 越境ECとは、国境を越えてオンラインで販売すること
  • Payoneer は、クロスボーダー決済プラットフォーム
  • 海外でビジネス展開するには
    • 現地法人の設立
    • 現地銀行口座の開設
  • Payoneer のアカウントがあれば OK
  • Payoneer の2005年に設立。本社は NY、日本法人も
  • 各国の規制に対応
    • 米国の貨幣サービス業務(MSB)
    • EUの電子マネー(E-Money)発行者
    • 香港の MSO
  • 外貨($, €, £)で受け取って、国内銀行口座にへ送金可能



 

ライフスタイルを変えた越境ECで月商4000万

小川 貴弘 氏(株式会社ターム)

  • なぜ越境EC?
    • 国内消費市場の縮小
    • 海外の市場規模の大きさ
    • サービスインフラ(特に物流)の整備
      • 現在は UPS, DHL を使用。日本郵便の UGX にも期待
  • 海外で売れるポイント
    • 価格が安い、商品が多い、納品日数が早い
  • 販路は Amazon.com
    • 圧倒的な集客力
    • 物流体制(FBA)
    • 販売しやすいマーケットプレイス
      • データも取れる
    • 海外銀行口座がなくても受取可能
      • 3年前まではダメだったが、Payoneer アカウントを使えば OK
  • Amazon FBA 販売
    • Amazon が出品者の商品在庫の保管、注文管理、出荷、カスタマーサービスを代行し、出品者の Amazon での販売を代行してくれるサービス
  • 会社間(BtoB)の取引にも Payoneer が使えるので便利


 

参考

国際宅配便(FedEx・DHL・UPS)について
EMSなど国際郵便の種類や特徴と料金比較 | ニッポンを届けたい!



 

今こそ海外展開を Amazon で

増田 航 氏(アマゾンジャパン株式会社 Amazon Global Selling)

  • 日本の EC市場 8兆円に対して、世界EC市場は16倍の127兆円(ゴールドマン・サックス調べ)
    • EC市場の成長率は中国が最も高い
    • 日本市場の伸び率が鈍化してきている
    • 北米・西欧は二桁%成長でまだ鈍化していない
  • BtoC-EC業界の世界ナンバーワン企業は、Amazon.com(経産省調べ)
  • Amazon は14カ国で展開中
    • (進出した順に)米・英・独・日・仏・加・中・伊・日・伯・印・墨・豪・蘭
  • アマゾンマーケットプレイスは 11ヶ国で展開中
  • FBA(Fulfillment by Amazon)
    • 受注機会の拡大(24時間365日)
      • ① カスタマーサポートがほとんど不要(英語でのカスタマーサポート 24時間365日)
      • ② 配送スピード(2日以内を担保)
      • ③ アマゾンプライム会員へのリーチ(米人口の 7人に1人がプライム会員。FBA は送料無料)
    • 振り込みは米ドル
      • 日本の銀行口座では受け取りできないので、Payoneer が必要


 

越境ECビジネスで使える配送とは

上杉 真一郎 氏(日本郵便株式会社)

  • BtoC・・・直接配送(直送)
    • 国際郵便・宅配クーリエ など
  • BtoBtoC・・・現地物流倉庫に一括輸送、物流倉庫から購入者に国内配送
    • FBA など
  • 国内配送と国際配送の違い
    • 1. 通関検査
      • 関税の徴収、輸出・輸入をしてはいけない品物の持ち込み・持ち出しを防ぐといった目的で行われる
    • 2. 海外への配送
      • Invoice, Packing list など
    • 3. 国際配送のための梱包
      • 国内と同じ梱包レベルでは厳しい
  • 通関検査(郵便通関)の場合は、必要な書類の内容で税関が判断するため、問い合わせが来ないようになるべく詳細を記載すること
  • 直送の場合は、購入者に関税が発生する可能性とその場合の対応についてお知らせをしておくこと
  • 国によっては郵送できないものもある(中国など)
    • JP の「国際郵便条件表」を確認
    • リチウム電池を含む商品を発送するには条件がある
  • 国際輸送の場合は、約10箇所の通過ポイントが必要(国内は約4箇所)
    • より強固な梱包が必要
    • 国際配送に「こわれもの」扱いは無い!!
  • 直送で一番使われているのは、EMS(国際スピード郵便)
  • ニーズに合った発送手段
    • EMS(国際スピード郵便)のほか、軽量なものは「国際 eパケット」、さらに小さい小包は「SAL便」もある
    • UBX(ゆうグローバルエクスプレス)
      • 関税元払い、複数個口扱いに対応
      • BtoBでの輸送はもちろん、FBAなどの BtoBtoC への配送にも適している
      • EMSのサイズや重さを超える荷物の取り扱いが可能
    • TOLLの国際物流サービス
  • US で優遇措置スタート(3/10より)
    • 個人輸入の場合に限り、商品代金+送料+保険料総額が $800以内であれば関税なし(3/10以前は $200 だった)


 

参考

国際宅配便の料金比較サイト
国際宅配便とEMSの料金検索 - 送料の虎




世界最大の中国卸売市場とOEM商品制作について 3国間貿易!日本に居ながら、中国でOEM制作し、米国FBA納品と販売

豊田 昇 氏(株式会社LuCent)

  • 中国から安く輸入して Amazon で高く売る
  • 検品・梱包・発送、インボイスの作成などを、個人や中小企業に代わって代行
  • 桜トレード代行サービス開始
    • 上海・深センで物流倉庫を確立、香港経由で配送、LAで荷受け
  • 米国のEC市場規模は、日本の4.3倍。中国は日本の約6倍

「第3回CodeIQ感謝祭「春のエンジニアまつり」」に参加しました

主催

CodeIQ

会場

東京都千代田区丸の内1-9-2 グラントウキョウサウスタワー41F




少し前に参加した勉強会。
特定の技術にフォーカスしたものではなく、エンジニアのキャリアについてのトピックが多かったように思います。

あと、芸人の厚切りジェイソンこと Jason Danielson 氏が登壇するということもあって、夕方頃から急に参加者が増えて満員状態になりました。
すごい人気ですね。


今回は、LTを除いたセッションで気になったことをメモ書き。


 

情報共有から始めるチーム開発とキャリア戦略

及川卓也氏


及川氏と言えば、昨年、米Google から日本のスタートアップの Qiita に転職して話題になりましたね。

グーグルでChrome開発に関わった及川卓也氏が「Qiita」開発元Incrementsの14人目の社員に | TechCrunch Japan


  • SECI(セキ)モデル
    • 共同化(暗黙知→暗黙知)いわゆる「俺の背中から学べ!」モデル
    • 表出化(暗黙知→形式知)
    • 連結化(形式知→形式知)
    • 内面化(形式知→暗黙知)
  • 共有を阻害するもの
    • 情報漏洩リスクへの不安
    • 共有することへの理解・共感不足
    • システム・ルール、そして文化情勢で解決?
  • Google では "Share Everything You Can"
    • Google Resume
    • Weekly Snipets
    • Codebase (Repository)
  • フロー型(リアルタイム型)か、ストック型(非同期型)か?
    • Slack はただのチャットではない
      • パーマリンク
      • チャンネルを自由に増やせる
      • DM
      • リアクション
      • 検索機能
    • Slack は、リアルタイム型・非同期型、対面型・分散型のいずれにも当てはまるのでは?
    • Slack はフロー情報、Qiita Team はストック情報・・では無い?
  • メンタルモデルをネットワーク型にする必要がある


SECI(セキ)モデルを理解するには、この本がオススメとのこと。

アジャイル開発とスクラム 顧客・技術・経営をつなぐ協調的ソフトウェア開発マネジメント

アジャイル開発とスクラム 顧客・技術・経営をつなぐ協調的ソフトウェア開発マネジメント



 

皆さん、はじめまして 株式会社メディアドゥです

森川晃氏

  • 著作物のデジタル流通を担う電子書籍取次
  • 著作物は「文化の発展に寄与」(著作権法第一条)

(目的)
第一条  この法律は、著作物並びに実演、レコード、放送及び有線放送に関し著作者の権利及びこれに隣接する権利を定め、これらの文化的所産の公正な利用に留意しつつ、著作者等の権利の保護を図り、もつて文化の発展に寄与することを目的とする。

  • どの本が売れているか、などのデータも武器になる
  • 電子書籍事業を始めるための4要素が揃っている唯一の企業
    • データベース、CMS、ビューア、コンテンツ
  • データベースは、Oracle Exadata X5
    • 約1.6億ダウンロード/月、約3ペタバイト配信/月
  • LINEマンガ、dブックでも導入




 

澤円の“リアル”プレゼン塾

澤円氏(マイクロソフトテクノロジーセンター)

【参考】


  • プレゼン三層構造
    • ビジョン = Why:何のためのプレゼンか?
    • 核 = What:何を伝えるプレゼンか?
    • 話術 = How:どうやって?
  • ビジョンと核が重要
  • ビジョン
    • ビジョンは究極の理想の形。変更不可
    • 「プレゼン終了後、聴衆にどうなってほしいか?」を決める
    • プレゼンは相手に行動させるためにするべし
    • プレゼンには「未来」を描け!
    • ただの報告はメールで十分。時間と空間の共有は貴重
    • 聴衆がプレゼンの後で他の人にワンセンテンスで内容を説明できるもの
    • 聴衆がプレゼンの後で他の人にどうしても教えたくなってしまうもの
    • シンプルであること
    • アクションの明確化を。誰が、何を、いつまでに
  • スライド作成のコツ
    • スライド1枚にテーマ(問題提起)1つ、説明3行
  • 話術のコツ
    • 口ぐせ、よく使う言い回しを気にする余裕を持つ
    • 視線の練習。電車に乗っている人たちの顔を短時間ずつ均等に眺めてみる
    • 背中で語らない
    • 笑顔。への字口は絶対ダメ
    • 話す速度よりもゆっくりと歩く(動く)と堂々と見せることができる
    • 手の動きは重要


 
澤円氏の本。




 

パネルディスカッション

Jason Danielson氏、及川卓也氏、澤円氏、増井雄一郎氏、星野俊介氏

  • ワークスタイルの違い
    • 大手は定時・残業という概念がない
    • ベンチャーは赤字なので頑張らないと自分も儲からない
    • 時間の感覚が違う。日本は「開始」時間に厳しい
    • 日本のナレッジワーカーの効率が計測できていないので、精神論になってしまっている
    • マネージャーの能力がイケてない。部下が目の前にいないと不安になる
    • 日本のクビに出来ないカルチャーがよくない。年功序列評価の影響
    • アメリカでクビになるのは、能力が低くてパフォーマンスが出ない人、あるいは部署自体がなくなる場合
    • 成長していかないとダメ。成長できない人が職場にのさばっていると組織が腐ってしまう
    • アメリカではボトム 5%が常にクビ候補
  • キャリアの違い
    • 日本人は給料の交渉をしないから給料が低い
    • ジョブ・ディスクリプションによって給料がほぼ決まっている
    • アメリカでは何歳でもコードを書けるが、マネージャになると責任が重くなるので給料が高くなるし、解雇リスクも高くなる
    • コードで人を評価するのは難しい。評価メトリクスを言語化するのは難しいので、それができる組織が限られる
    • 下支えのためのコードが評価されない傾向
    • 日本はソフトウェアを舐めすぎている?
    • 外資や海外で働くために一番必要なのはコミュニケーション
    • やりたいことを言語化すること
    • 最初の一歩をオープンソースのパッチから始めるのがよいかも
  • ポジティブな話
    • 厳しい世界に出ると自分を伸ばせる
    • 日本はぬるま湯、世界にはチャンスや成長の機会がたくさんある
    • ビジネスは、時間や言語のギャップを利用したものが多い
    • とにかく何でもいいからグローバルに接点をもってアウトプットをしていくこと
    • やりたいことは自分で決めてやればいい。諦めなければいずれ成功できる


 

考える力

Jason Danielson氏(株式会社テラスカイ)

  • 勉強のための勉強はつまらない
  • やりたいことをずっと長い間やることで、やろうとしていることができるようになる
  • 若い頃から出世がしたかったが、ある頃から仕事だけじゃないと感じるようになった
  • IT業界のスピードがすごい。30年でここまで変化があるのは、IT業界だけ
  • 変化させるのに何十年かかる古臭い企業の考え方は、IT企業には合わない
    • ソフトウェアを5年かけて開発すると、市場が全然違ってしまっている
    • 日本の企業は時間を掛けすぎている
    • i-modeはそれにどれだけの価値があるのかを作った人たちが分かってなかったが、Appleは違った
  • 情報はまず英語で入ってくる
    • 英語ができるとそれだけで情報量が違う
  • 人生は仕事だけじゃない
    • ITと全く関係ないこともやった方がいい。新しいことをやってみてほしい
  • やっていることを考えてほしい。「やれと言われているので」はダメ
    • 理由がわかるまではやらない方がマシ
    • 新機能作ったら使われるんですか?どういう価値があるんですか?どれだけ売れるんですか?
  • 価値を出そう
    • 実際の価値は、問題を解決しているかどうか


芸人「厚切りジェイソン」のまじめな啓発本。Twitter 界隈では有名。

日本のみなさんにお伝えしたい48のWhy (ぴあ書籍)

日本のみなさんにお伝えしたい48のWhy (ぴあ書籍)

Mezzanine プロジェクトの開発環境を PyCharm で設定する

はじめに

以前に「見よ!これが Python製の WordPress風フルスタックCMSフレームワーク「Mezzanine(メザニン)」だ!」という記事で、Python製の WordPress風フルスタックCMSフレームワーク「Mezzanine」を紹介しましたが、今回は、その Mezzanine プロジェクトの開発環境を、Mac版 PyCharm Professional Edition で設定するための手順を書いてみます。


PyCharm Professional Edition は Homebrew-Cask でインストールしています。

<過去記事>
akiyoko.hatenablog.jp

PyCharm の初期設定は済んでいるという前提で進めます。

<過去記事>
akiyoko.hatenablog.jp

やりたいこと

  • 最新版の Mezzanine プロジェクトを Vagrant サーバにインストール
  • Vagrant サーバと Mac上の PyCharm とのソースコード同期設定
  • リモートデバッグ設定
  • Mezzanine テーマを変更

環境

<クライアント>

  • Mac OS X 10.10.5
  • PyCharm (Professional Edition) 5.0.4

<サーバ>

  • Ubuntu 14.04 LTS(on Vagrant)
    • IPアドレス:192.168.33.103
    • ログインユーザ:vagrant

<Mezzanineプロジェクト>

  • Django 1.9.5
  • Mezzanine 4.1.0
  • Cartridge 0.11.0



 

1. PyCharm の設定(1)

1.1. Pure Python Project を作成

PyCharm を起動し、 [Create New Project] をクリックします。

[Pure Python] を選択し、

Location /Users/akiyoko/PycharmProjects/mezzanine_project
Interpreter (適当)

を設定します。Interpreter は、後でリモート側の virtualenv のものに変更するので、ここでは適当なものを選択しておきます。

f:id:akiyoko:20160313142425p:plain

ここで、[Django] プロジェクトではなく [Pure Python] を選択した理由は、[Pure Python] プロジェクトにしておかないとリモートデバッグ機能が使えない(はずだ)からです。


 

1.2. Vagrant連携

[Tools] > [Vagrant] > [Init in Project Root] を選択します。


PyCharm 上で、Vagrantfile を開いて編集します。

<変更後>

  config.vm.network "private_network", ip: "192.168.33.103"

[Tools] > [Vagrant] > [Up] でインスタンスを起動します。




 

2. Vagrantサーバの初期設定

Vagrant サーバに ssh で乗り込みます。

$ ssh vagrant@192.168.33.103

 

2.1. 最低限のインストール

$ sudo apt-get update
$ sudo apt-get -y install python-dev git tree

 

2.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.47, 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
参考



データベース、データベースユーザを作成します。
なお、データベース名は 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


 

2.3. 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.0 from /usr/local/lib/python2.7/dist-packages (python 2.7)

2.4. 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.5. Mezzanineプロジェクトを作成

Overview — Mezzanine 4.1.0 documentation
に従って、Mezzanineプロジェクトのインストールをします。

### Djangoプロジェクトの virtualenv 環境を設定して activate
$ mkvirtualenv myproject

### /opt/webapps 配下にプロジェクトの外箱を作成
$ sudo mkdir -p /opt/webapps/myproject
$ sudo chown -R `whoami`. /opt/webapps

### イメージライブラリのインストール
### http://mezzanine.jupo.org/docs/overview.html#dependencies
$ sudo apt-get -y install libjpeg8 libjpeg8-dev
$ sudo apt-get -y build-dep python-imaging

### MySQLライブラリのインストール
$ pip install MySQL-python

### Mezzanine プロジェクトを作成
$ cd /opt/webapps/myproject/
### Cartridge のインストール
$ pip install -U cartridge

$ pip list |grep Django
Django (1.9.5)
$ pip list |grep Mezzanine
Mezzanine (4.1.0)
$ pip list |grep Cartridge
Cartridge (0.11.0)

### プロジェクトのディレクトリ構造は
### myproject/ as <repository_root> also as <django_project_root>
### └─ config/ as <configuration_root>
$ mezzanine-project -a cartridge config .

$ tree -a /opt/webapps/myproject/
/opt/webapps/myproject/
├── config
│   ├── dev.db
│   ├── __init__.py
│   ├── local_settings.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── deploy
│   ├── crontab.template
│   ├── gunicorn.conf.py.template
│   ├── local_settings.py.template
│   ├── nginx.conf.template
│   └── supervisor.conf.template
├── .DS_Store
├── fabfile.py
├── .gitignore
├── .hgignore
├── __init__.py
├── manage.py
└── requirements.txt

 

2.6. Django のデータベース設定を変更

### デフォルトで用意されている config/dev.db は不要なので削除
$ rm config/dev.db

### MySQL用の設定変更
$ vi config/local_settings.py

<変更前>
---
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": "dev.db",
        "USER": "",
        "PASSWORD": "",
        "HOST": "",
        "PORT": "",
    }
}
---

<変更後>
---
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "NAME": "myproject",
        "USER": "myprojectuser",
        "PASSWORD": "myprojectuserpass",
        "HOST": "localhost",
        "PORT": "",
    }
}


 

2.7. デモ用のレコードを投入

createdb でデモ用のレコードを投入することができます。

### migrate実行
### --noinput オプションを付けると、デモ用の初期データ(site, superuser, 画像などのコンテンツ, etc)を自動登録
### --nodata オプションを付けると、デモ用画像やギャラリーなどのコンテンツを static 配下に自動作成しない
$ python manage.py createdb --noinput

### とりあえずデータベースをバックアップ
### 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.8. runserver で起動

$ python manage.py runserver 0.0.0.0:8000

http://192.168.33.103:8000/admin/
にブラウザからアクセスします。
(admin/default)


疎通がOKなら、runserver を一旦停止します。


 

3. PyCharm の設定(2)

3.1. デプロイ先サーバ設定

[Tools] > [Deployment] > [Options] の [Exclude items by name] に以下を設定します。

.svn;.cvs;.idea;.DS_Store;.git;.hg;.vagrant;Vagrantfile;*.pyc;*.swp;*.db;*.sock;*.pid

f:id:akiyoko:20160625112113p:plain

[Tools] > [Deployment] > [Configuration] で設定画面を開き、「+」ボタンをクリックしてサーバの設定を追加します。

Name mezzanine_project
Type SFTP

f:id:akiyoko:20160313155825p:plain

各種設定をします。

[Connection]

[Visible only for this project] にチェックを入れます。

SFTP host 192.168.33.103
Port 22
Root path /([Autodetect] はクリックしない。「/home/vagrant」だとファイルを同期ダウンロードできなくなる)
User name vagrant
Password vagant([Save password] にチェックを入れる)

f:id:akiyoko:20160313155856p:plain

[Mappings]

[Use this server as default] をクリックします。

Local path /Users/akiyoko/PycharmProjects/mezzanine_project(デフォルトのまま)
Deployment path /opt/webapps/myproject

f:id:akiyoko:20160313155920p:plain


 

3.2. ソースコードの同期

プロジェクトで右クリック > [Deployment] > [Download from mezzanine_project] を選択して、Vagrantサーバから PyCharm にプロジェクトをダウンロードします。


ここで、[Tools] > [Deployment] > [Automatic Upload] にチェックを入れます。


 

3.3. ローカル側でソースコードを Git管理

まず、不要なファイルを削除します。
Mercurialは使わないので .hgignore を Projectペイン上で削除します。


次に、PyCharm の Terminal を開きます。

まだ git config -l の設定をしていなければ、PyCharm の Terminal で以下を設定します。

$ cd ~/PycharmProjects/mezzanine_project/
$ git config --global user.name akiyoko
$ git config --global user.email akiyoko@users.noreply.github.com
$ git config --global color.ui auto

git init する前に、.gitignore に PyCharm 用の設定を追加しておきます。

.gitignore

*.pyc
*.pyo
*.db
.DS_Store
.coverage
local_settings.py
/static

# PyCharm
.idea/
.vagrant/
Vagrantfile


一旦コミットします。

$ git init
$ git add .
$ git commit -m "Initial commit"

 

3.4. Project Interpreter の設定

[Preferences] > [Project: mezzanine_project] > [Project Interpreter] から、[Python Interpreter] の右側の歯車アイコンをクリックし、[Add Remote] を選択します。


[Vagrant] を選択し、

Vagrant Instance Folder /Users/akiyoko/PycharmProjects/mezzanine_project(デフォルトのまま)
Vagrant Host URL ssh://vagrant@127.0.0.1:2222(デフォルトのまま)
Python interpreter path /home/vagrant/.virtualenvs/myproject/bin/python

を入力して、OK をクリックします。

f:id:akiyoko:20160313160715p:plain

作成した Remote Interpreter が選択されていることを確認して、[OK] をクリックします。



ここで、Python モジュールに参照エラーが出ないようにするために、[File] > [Invalidate Caches / Restart] を選択し、[Invalidate and Restart] をクリックして、PyCharm を再起動しておきます。


 

3.5. Run/Debug設定

Project ペインの manage.py ファイルで右クリック > [Create "manage"] を選択します。

Name manage
Script 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/mezzanine_project (/home/vagrant/.virtualenvs/myproject/bin/python))
Working directory /opt/webapps/myproject
Path mappings - Local path /Users/akiyoko/PycharmProjects/mezzanine_project
Path mappings - Remote path /opt/webapps/myproject

ここで、「Add content roots to PYTHONPATH」と「Add source roots to PYTHONPATH」のチェックを外します。

f:id:akiyoko:20160314074038p:plain

デバッグ実行できるか確認できれば、OKです。




 

3.6. テンプレート設定

ここで、Mezzanine本体の templates をコピーしておきます。

Vagrant サーバ側で、

$ cd /opt/webapps/myproject/
### Mezzanine のテンプレートをコピー
$ cp -a ~/.virtualenvs/myproject/lib/python2.7/site-packages/mezzanine/core/templates .
### Cartridge のテンプレートをコピー
$ cp -a ~/.virtualenvs/myproject/lib/python2.7/site-packages/cartridge/shop/templates .

を実行した後、PyCharm 上でファイルを同期(ダウンロード)します。


テンプレート(htmlファイル)が参照エラーで真っ赤に染まってしまっている場合は、[Preferences] > [Languages & Frameworks] > [Python Template Languages] から、「Template language」を「Django」に設定すれば解消するはずです。

f:id:akiyoko:20160313161637p:plain






 

4. テーマ変更

参考


試しに、
https://github.com/thecodinghouse/mezzanine-themes.git
の moderna テーマを入れてみます。


ローカル側で、以下を実行します。

$ cd ~/dev/
$ git clone https://github.com/thecodinghouse/mezzanine-themes.git
$ cp -a mezzanine-themes/moderna ~/PycharmProjects/mezzanine_project/

コマンドでコピーしたファイルはサーバ側に自動転送されないので、[Deployment] > [Upload to mezzanine_project] で手動アップロードしておきます。


コピーしたテーマを Djangoアプリケーションとして設定するために、config/settings.py の INSTALLED_APPS の最後、および TEMPLATES/DIRS の先頭に追加します。

config/settings.py

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [
            os.path.join(PROJECT_ROOT, "moderna/templates"),
            os.path.join(PROJECT_ROOT, "templates")
        ],
        "APP_DIRS": True,
        ・
        ・
]

INSTALLED_APPS = (
    ・
    ・
    "mezzanine.twitter",
    # "mezzanine.accounts",
    # "mezzanine.mobile",
    "moderna",
)

まとめ

Mezzanine は普通の Django プロジェクトなので、インストールやテンプレートの設定自体は Django のものと何ら変わりません。


あとはドキュメントを読むだけですね。

Mezzanine — Mezzanine 4.1.0 documentation



 

参考

最新版 Mezzanine インストール時のパッケージ情報
$ pip freeze
beautifulsoup4==4.4.1
bleach==1.4.2
Cartridge==0.11.0
chardet==2.3.0
Django==1.9.5
django-contrib-comments==1.7.0
filebrowser-safe==0.4.3
future==0.15.2
grappelli-safe==0.4.2
html5lib==0.9999999
Mezzanine==4.1.0
MySQL-python==1.2.5
oauthlib==1.0.3
Pillow==3.2.0
PyPDF2==1.25.1
pytz==2016.3
reportlab==3.3.0
requests==2.9.1
requests-oauthlib==0.6.1
six==1.10.0
tzlocal==1.2.2
xhtml2pdf==0.0.6


 

各種 URLconf

config/urls.py

from __future__ import unicode_literals

from django.conf.urls import include, url
from django.conf.urls.i18n import i18n_patterns
from django.contrib import admin
from django.views.i18n import set_language
from mezzanine.core.views import direct_to_template
from mezzanine.conf import settings

from cartridge.shop.views import order_history


admin.autodiscover()

# Add the urlpatterns for any custom Django applications here.
# You can also change the ``home`` view to add your own functionality
# to the project's homepage.

urlpatterns = i18n_patterns(
    # Change the admin prefix here to use an alternate URL for the
    # admin interface, which would be marginally more secure.
    url("^admin/", include(admin.site.urls)),
)

if settings.USE_MODELTRANSLATION:
    urlpatterns += [
        url('^i18n/$', set_language, name='set_language'),
    ]

urlpatterns += [

    # Cartridge URLs.
    url("^shop/", include("cartridge.shop.urls")),
    url("^account/orders/$", order_history, name="shop_order_history"),

    # We don't want to presume how your homepage works, so here are a
    # few patterns you can use to set it up.

    # HOMEPAGE AS STATIC TEMPLATE
    # ---------------------------
    # This pattern simply loads the index.html template. It isn't
    # commented out like the others, so it's the default. You only need
    # one homepage pattern, so if you use a different one, comment this
    # one out.

    url("^$", direct_to_template, {"template": "index.html"}, name="home"),

    # HOMEPAGE AS AN EDITABLE PAGE IN THE PAGE TREE
    # ---------------------------------------------
    # This pattern gives us a normal ``Page`` object, so that your
    # homepage can be managed via the page tree in the admin. If you
    # use this pattern, you'll need to create a page in the page tree,
    # and specify its URL (in the Meta Data section) as "/", which
    # is the value used below in the ``{"slug": "/"}`` part.
    # Also note that the normal rule of adding a custom
    # template per page with the template name using the page's slug
    # doesn't apply here, since we can't have a template called
    # "/.html" - so for this case, the template "pages/index.html"
    # should be used if you want to customize the homepage's template.
    # NOTE: Don't forget to import the view function too!

    # url("^$", mezzanine.pages.views.page, {"slug": "/"}, name="home"),

    # HOMEPAGE FOR A BLOG-ONLY SITE
    # -----------------------------
    # This pattern points the homepage to the blog post listing page,
    # and is useful for sites that are primarily blogs. If you use this
    # pattern, you'll also need to set BLOG_SLUG = "" in your
    # ``settings.py`` module, and delete the blog page object from the
    # page tree in the admin if it was installed.
    # NOTE: Don't forget to import the view function too!

    # url("^$", mezzanine.blog.views.blog_post_list, name="home"),

    # MEZZANINE'S URLS
    # ----------------
    # ADD YOUR OWN URLPATTERNS *ABOVE* THE LINE BELOW.
    # ``mezzanine.urls`` INCLUDES A *CATCH ALL* PATTERN
    # FOR PAGES, SO URLPATTERNS ADDED BELOW ``mezzanine.urls``
    # WILL NEVER BE MATCHED!

    # If you'd like more granular control over the patterns in
    # ``mezzanine.urls``, go right ahead and take the parts you want
    # from it, and use them directly below instead of using
    # ``mezzanine.urls``.
    url("^", include("mezzanine.urls")),

    # MOUNTING MEZZANINE UNDER A PREFIX
    # ---------------------------------
    # You can also mount all of Mezzanine's urlpatterns under a
    # URL prefix if desired. When doing this, you need to define the
    # ``SITE_PREFIX`` setting, which will contain the prefix. Eg:
    # SITE_PREFIX = "my/site/prefix"
    # For convenience, and to avoid repeating the prefix, use the
    # commented out pattern below (commenting out the one above of course)
    # which will make use of the ``SITE_PREFIX`` setting. Make sure to
    # add the import ``from django.conf import settings`` to the top
    # of this file as well.
    # Note that for any of the various homepage patterns above, you'll
    # need to use the ``SITE_PREFIX`` setting as well.

    # url("^%s/" % settings.SITE_PREFIX, include("mezzanine.urls"))

]

# Adds ``STATIC_URL`` to the context of error pages, so that error
# pages can use JS, CSS and images.
handler404 = "mezzanine.core.views.page_not_found"
handler500 = "mezzanine.core.views.server_error"


/home/vagrant/.virtualenvs/myproject/local/lib/python2.7/site-packages/mezzanine/urls.py

"""
This is the main ``urlconf`` for Mezzanine - it sets up patterns for
all the various Mezzanine apps, third-party apps like Grappelli and
filebrowser.
"""

from __future__ import unicode_literals
from future.builtins import str

from django.conf.urls import include, url
from django.contrib.sitemaps.views import sitemap
from django.views.i18n import javascript_catalog
from django.http import HttpResponse

from mezzanine.conf import settings
from mezzanine.core.sitemaps import DisplayableSitemap


urlpatterns = []

# JavaScript localization feature
js_info_dict = {'domain': 'django'}
urlpatterns += [
    url(r'^jsi18n/(?P<packages>\S+?)/$', javascript_catalog, js_info_dict),
]

if settings.DEBUG and "debug_toolbar" in settings.INSTALLED_APPS:
    try:
        import debug_toolbar
    except ImportError:
        pass
    else:
        urlpatterns += [
            url(r'^__debug__/', include(debug_toolbar.urls)),
        ]

# Django's sitemap app.
if "django.contrib.sitemaps" in settings.INSTALLED_APPS:
    sitemaps = {"sitemaps": {"all": DisplayableSitemap}}
    urlpatterns += [
        url("^sitemap\.xml$", sitemap, sitemaps),
    ]

# Return a robots.txt that disallows all spiders when DEBUG is True.
if getattr(settings, "DEBUG", False):
    urlpatterns += [
        url("^robots.txt$", lambda r: HttpResponse("User-agent: *\nDisallow: /",
                                                   content_type="text/plain")),
    ]

# Miscellanous Mezzanine patterns.
urlpatterns += [
    url("^", include("mezzanine.core.urls")),
    url("^", include("mezzanine.generic.urls")),
]

# Mezzanine's Accounts app
if "mezzanine.accounts" in settings.INSTALLED_APPS:
    # We don't define a URL prefix here such as /account/ since we want
    # to honour the LOGIN_* settings, which Django has prefixed with
    # /account/ by default. So those settings are used in accounts.urls
    urlpatterns += [
        url("^", include("mezzanine.accounts.urls")),
    ]

# Mezzanine's Blog app.
blog_installed = "mezzanine.blog" in settings.INSTALLED_APPS
if blog_installed:
    BLOG_SLUG = settings.BLOG_SLUG.rstrip("/") + "/"
    blog_patterns = [
        url("^%s" % BLOG_SLUG, include("mezzanine.blog.urls")),
    ]
    urlpatterns += blog_patterns

# Mezzanine's Pages app.
PAGES_SLUG = ""
if "mezzanine.pages" in settings.INSTALLED_APPS:
    # No BLOG_SLUG means catch-all patterns belong to the blog,
    # so give pages their own prefix and inject them before the
    # blog urlpatterns.
    if blog_installed and not BLOG_SLUG.rstrip("/"):
        PAGES_SLUG = getattr(settings, "PAGES_SLUG", "pages").strip("/") + "/"
        blog_patterns_start = urlpatterns.index(blog_patterns[0])
        urlpatterns[blog_patterns_start:len(blog_patterns)] = [
            url("^%s" % str(PAGES_SLUG), include("mezzanine.pages.urls")),
        ]
    else:
        urlpatterns += [
            url("^", include("mezzanine.pages.urls")),
        ]


/home/vagrant/.virtualenvs/myproject/local/lib/python2.7/site-packages/mezzanine/core/urls.py

from __future__ import unicode_literals

from django.conf.urls import url
from django.contrib.auth import views as auth_views

from mezzanine.conf import settings
from mezzanine.core import views as core_views


urlpatterns = []

if "django.contrib.admin" in settings.INSTALLED_APPS:
    urlpatterns += [
        url("^password_reset/$", auth_views.password_reset,
            name="password_reset"),
        url("^password_reset/done/$", auth_views.password_reset_done,
            name="password_reset_done"),
        url("^reset/done/$", auth_views.password_reset_complete,
            name="password_reset_complete"),
        url("^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$",
            auth_views.password_reset_confirm, name="password_reset_confirm"),
    ]

urlpatterns += [
    url("^edit/$", core_views.edit, name="edit"),
    url("^search/$", core_views.search, name="search"),
    url("^set_site/$", core_views.set_site, name="set_site"),
    url("^set_device/(?P<device>.*)/$", core_views.set_device,
        name="set_device"),
    url("^asset_proxy/$", core_views.static_proxy, name="static_proxy"),
    url("^displayable_links.js$", core_views.displayable_links_js,
        name="displayable_links_js"),
]


/home/vagrant/.virtualenvs/myproject/local/lib/python2.7/site-packages/mezzanine/generic/urls.py

from __future__ import unicode_literals

from django.conf.urls import url

from mezzanine.generic import views


urlpatterns = [
    url("^admin_keywords_submit/$", views.admin_keywords_submit,
        name="admin_keywords_submit"),
    url("^rating/$", views.rating, name="rating"),
    url("^comment/$", views.comment, name="comment"),
]


/home/vagrant/.virtualenvs/myproject/local/lib/python2.7/site-packages/mezzanine/blog/urls.py

from __future__ import unicode_literals

from django.conf.urls import url

from mezzanine.blog import views
from mezzanine.conf import settings


# Trailing slahes for urlpatterns based on setup.
_slash = "/" if settings.APPEND_SLASH else ""

# Blog patterns.
urlpatterns = [
    url("^feeds/(?P<format>.*)%s$" % _slash,
        views.blog_post_feed, name="blog_post_feed"),
    url("^tag/(?P<tag>.*)/feeds/(?P<format>.*)%s$" % _slash,
        views.blog_post_feed, name="blog_post_feed_tag"),
    url("^tag/(?P<tag>.*)%s$" % _slash,
        views.blog_post_list, name="blog_post_list_tag"),
    url("^category/(?P<category>.*)/feeds/(?P<format>.*)%s$" % _slash,
        views.blog_post_feed, name="blog_post_feed_category"),
    url("^category/(?P<category>.*)%s$" % _slash,
        views.blog_post_list, name="blog_post_list_category"),
    url("^author/(?P<username>.*)/feeds/(?P<format>.*)%s$" % _slash,
        views.blog_post_feed, name="blog_post_feed_author"),
    url("^author/(?P<username>.*)%s$" % _slash,
        views.blog_post_list, name="blog_post_list_author"),
    url("^archive/(?P<year>\d{4})/(?P<month>\d{1,2})%s$" % _slash,
        views.blog_post_list, name="blog_post_list_month"),
    url("^archive/(?P<year>\d{4})%s$" % _slash,
        views.blog_post_list, name="blog_post_list_year"),
    url("^(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/"
        "(?P<slug>.*)%s$" % _slash,
        views.blog_post_detail, name="blog_post_detail_day"),
    url("^(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<slug>.*)%s$" % _slash,
        views.blog_post_detail, name="blog_post_detail_month"),
    url("^(?P<year>\d{4})/(?P<slug>.*)%s$" % _slash,
        views.blog_post_detail, name="blog_post_detail_year"),
    url("^(?P<slug>.*)%s$" % _slash,
        views.blog_post_detail, name="blog_post_detail"),
    url("^$", views.blog_post_list, name="blog_post_list"),
]


/home/vagrant/.virtualenvs/myproject/local/lib/python2.7/site-packages/mezzanine/pages/urls.py

from __future__ import unicode_literals

from django.conf.urls import url
from django.conf import settings

from mezzanine.pages import page_processors, views


page_processors.autodiscover()

# Page patterns.
urlpatterns = [
    url("^admin_page_ordering/$", views.admin_page_ordering,
        name="admin_page_ordering"),
    url("^(?P<slug>.*)%s$" % ("/" if settings.APPEND_SLASH else ""),
        views.page, name="page"),
]


/home/vagrant/.virtualenvs/myproject/local/lib/python2.7/site-packages/cartridge/shop/urls.py

from __future__ import unicode_literals

from django.conf.urls import url
from mezzanine.conf import settings

from cartridge.shop import views


_slash = "/" if settings.APPEND_SLASH else ""

urlpatterns = [
    url("^product/(?P<slug>.*)%s$" % _slash, views.product,
        name="shop_product"),
    url("^wishlist%s$" % _slash, views.wishlist, name="shop_wishlist"),
    url("^cart%s$" % _slash, views.cart, name="shop_cart"),
    url("^checkout%s$" % _slash, views.checkout_steps, name="shop_checkout"),
    url("^checkout/complete%s$" % _slash, views.complete,
        name="shop_complete"),
    url("^invoice/(?P<order_id>\d+)%s$" % _slash, views.invoice,
        name="shop_invoice"),
    url("^invoice/(?P<order_id>\d+)/resend%s$" % _slash,
        views.invoice_resend_email, name="shop_invoice_resend"),
]