ASINからあさましリンクを生成するカスタムテンプレートタグ。

 Python プログラマのための Django テンプレート言語ガイド
 Amazon.co.jp アソシエイト・プログラム: アマゾンのアフィリエイトで副収入!
 Amazon.co.jpメッセージ

 思い出した様に書いてみるDjangoネタなエントリー。や、本当に思い出しただけなんだけどね。

 当ページのトップページ右にありますサイドバー内のあさましリンクは、Amazon Web サービスより商品名、価格などを取り出して表示しておりますが、それにはカスタムテンプレートタグ(←埋め込みタグ)という仕組みを利用しています。
 カスタムテンプレートタグの詳細に付きましては上記リンク先の、「Python プログラマのための Django テンプレート言語ガイド」をご参照下さいませ。後、基本的に下記参照記事「文字列を端折って表示するカスタムテンプレートフィルタ」の続きなので、そちらも見て頂けるとわかりやすいかと思います。まぁ、見たところでわかりやすくならないなんてのは容易に想像できたりしますけど。

 アマゾンのアソシエイトプログラム、Amazon Web サービスを使いますので、この2サービスへの事前登録が必要です。また、ElementTreeモジュールを使いますが、私はPython2.5を利用していますので標準モジュール扱いです。Django自体もPre版の0.96を利用していますが、こちらはあまり関係がないかと思います。
 処理の流れは、予めsettings.pyで設定しておいたアソシエイトタグ(←変数名AWS_ASSOCIATE_TAG)とアクセスキー(←変数名AWS_ACCESS_KEY_ID)を取り出して、引数で渡されるASIN(←アマゾンさんの商品ID)と共にAmazon Web サービスへ問い合わせ、返ってきたデータ(←この場合XMLですが)から必要な部分だけを取り出し辞書にする。それを専用に用意したテンプレートを用いて表示する。と言った単純なものです。そして例によってベタに書いております(←ベタにしかできないヤツ)。

 “ blog_extras.py”に追加したコードは以下の通り。

import urllib
from xml.etree import ElementTree

@register.inclusion_tag('amazon_asamashi.html')
def show_amazon_asamashi(asin):
    try:
        url = '{http://webservices.amazon.com/AWSECommerceService/2006-11-14}'
        xml = ElementTree.parse(urllib.urlopen("http://webservices.amazon.co.jp/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=" + settings.AWS_ACCESS_KEY_ID + "&AssociateTag=" + settings.AWS_ASSOCIATE_TAG + "&Operation=ItemLookup&ItemId=" + asin + "&ResponseGroup=Medium&Version=2006-11-14"))

        try:
            smallImageURL = xml.find(url + 'Items/' + url + 'Item/' + url + 'SmallImage/' + url + 'URL').text
        except:
            smallImageURL = "http://rcm-images.amazon.com/images/G/09/x-locale/detail/thumb-no-image._SL100_SCTZZZZZZZ_.jpg"

        item = {'url': xml.find(url + 'Items/' + url + 'Item/' + url + 'DetailPageURL').text,
                'imgsrc': smallImageURL,
                'title': xml.find(url + 'Items/' + url + 'Item/' + url + 'ItemAttributes/' + url + 'Title').text,
                'price': xml.find(url + 'Items/' + url + 'Item/' + url + 'OfferSummary/' + url + 'LowestNewPrice/' + url + 'FormattedPrice').text}
    except:
        item = None
    return {'item': item}

 一行目で使用するテンプレートを紐づけています、デコレータで(←デコレータって良くわかってないけど)。途中のネストしたtry句は、たまに画像のないアイテムがあるのでexceptして、決め打ちURLをねじ込んでいます。

 一応テンプレート“amazon_asamashi.html”の内容も記しておきますが、何と言う事もありません。

{% if item %}
    <a href="{{ item.url }}"><img src="{{ item.imgsrc }}" />{{ item.price }}<br />
    {{ item.title }}</a>
{% endif %}

 カスタムテンプレートタグを使うとほとんどの事ができるのだけど、少し複雑過ぎる様な気もする、別にファイルを用意してそちらへ記述しなければならないし。でも、「テンプレートには何も書かせないぜ(←ロジックの類い)」感はわかるし、支持もしたいのでこれでも良いかなぁ(←結局曖昧)。

ーー追記:'07/02/10ーー
 書くの忘れてた。実際にこのページで使っているのはASINをまとめて送り、データを一括して受け取るやり方です(←ASINを,で区切って渡せばOK)。連発してアクセスするのは気が引けるし、ただでさえ重いのにさらに重くなりそうだし。
 まぁ、違いは辞書で渡すかわりに辞書の入ったリストで送り、テンプレート側でfor文で回して表示しているだけなのですけど。