カートを実装してたらはまった
今まであまりセッションを意識せずに開発してたせいか、つまらないことですごくはまったのでメモしておく。
django のセッションはシンプルで、 request.session を辞書ライクに使えばいい。
なので今回は、商品名の配列とか合計金額を格納してカートを実装することにした。
def cart_add(request): ''' カートに商品を追加する。 ''' cart = request.session.get('cart', { 'total' : 0, 'items':[] }) cart['total'] += int(request.POST.get('price', 0)) cart['items'].append(request.POST.get('itemname', '') request.session['cart'] = cart #略 def cart_list(request): ''' カートの中身を表示する。 ''' return render_to_response('cart_list.html', { 'cart' : request.session.get('cart', { 'total' : 0, 'items':[] }), }, RequestContext(request)) def cart_clear(request): ''' カートの中身を消去する。 ''' if 'cart' in request.session: request.session['cart'] = { 'total' : 0, 'items':[] }
で、カートの初期値が何回も登場するので、一個所にまとめることにした。
CART_EMPTY = { 'total_price' : 0, 'items' : [], }
そうすると、cart_clearを実行してもなぜかカートの中身がクリアされなかったり、IEとFirefoxでカートの中身が共有されたりと、かなりヤバい現象が発生した。
前者については、セッションですらキャッシュが効くのか、とあまり深く考えていなかった。だが後者はいくらなんでもおかしすぎる。djangoがそんな仕様のわけがない。
原因としては呆れるほど単純だった。上記の書き方だと、CART_EMPTYという名前のオブジェクトをあちこちで共有してるにすぎない。だからカートの中身も共有されてしまってたんですな。変数名が大文字だからと言って、特別なわけじゃないんだよな・・・
で、とりあえずlambdaを使って毎回オブジェクトを生成するようにしたら、あっさり解決しました。我ながら情けない・・・
CART_EMPTY = (lambda:{ 'total_price' : 0, 'items' : [], })()