カート機能の作成方法
・viewsの流れ
①@require_POSTを使ってPOSTのみ受け付けるようにする
②メソッドにはrequestとproduct_idを指定する
③idと合致しないproduct_idの場合は404エラーを出すif文を記述する
④sessionの中にある、「カート」キーの商品の値を変数に代入
⑤cartが存在した場合はcartに追加し、追加したcartをsession["cart"]に代入しなおす。もしcartがない場合は新規のcartのリストを作成する
⑥reverse関数を使ってurlsで指定された名前を使って直接リダイレクトさせる
sessionは辞書のように使える。(詳しくは下記参照)
必要なインポート
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.views.decorators.http import require_POST
@require_POST
def cart_add(request, product_id):
#404エラーの条件分岐
if not Product.objects.filter(id=product_id).exists():
raise Http404
#sessionからcartのキーを取得している
cart = request.session.get("cart")
#cartがあれば、リストに追加しsessionのcartキーに値を追加する。
#product_idを追加するだけで、商品情報を追加できる。
if cart:
cart.append(product_id)
request.session["cart"] = cart
else:
#cartがなければcartを新規作成し、product_idを追加する
request.session["cart"] = [product_id]
return HttpResponseRedirect(reverse("product_list"))
テンプレート
<form method="post" action="{% url "cart_add" product.id %}">
{% csrf_token %}
<input type="submit" value="カートへ追加">
</form>
urls
path('cart/<int:product_id>/add/', cart.views.cart_add, name='cart_add'),
解説
・カートの処理
cart = request.session.get("cart")`:
セッションからカートを取得します。`"cart"`キーが存在しない場合、`get`メソッドは`None`を返します。
request.session["cart"] = cart`: 変更されたカートをセッションに保存します。これにより、ユーザーのカートの状態が更新されます。カートが存在しない場合、新しいカートを作成し、そのカートに製品IDをリストとして追加します。
・リダイレクト
return HttpResponseRedirect(reverse("product_list"))`:
ユーザーを製品リストページにリダイレクトします。
`reverse`関数は、URLのnameで指定されたurlに直接リダイレクトする。リダイレクトされるにはこの形が必要
商品のIDのみを渡すことで商品情報をいれることができる解説
商品の`product_id`のみをカートに追加するアプローチは、ショッピングカートの実装においてよく採用されるシンプルかつ効率的な方法です。この方法の背後にある考え方やその理由を以下に説明します。
### なぜ`product_id`のみを使用するのか
1. **効率性**: `product_id`は、データベースにおける商品を一意に識別するための最小限の情報です。これをキーとして使用することで、サーバー側で容易に商品の詳細情報(名前、価格、画像など)を取得できます。セッションやデータベースに商品の全データを保存するよりも、`product_id`を保存する方がはるかに効率的です。
2. **柔軟性**: 商品の価格や説明が変更された場合でも、`product_id`が変わることはありません。カート内で`product_id`のみを保持しておけば、最新の商品情報を常にデータベースから取得して表示することができます。これにより、古い情報がユーザーに表示されることを防ぎます。
3. **簡素化**: カートへの追加や削除、数量の変更など、カート操作を簡素化できます。`product_id`を基に操作を行うことで、コードが簡潔になり、メンテナンスや拡張も容易になります。
### 商品名やその他の情報はどうなるのか
- **商品情報の取得**: カートを表示する際、保存されている`product_id`を使用してデータベースから対応する商品情報を取得します。これにより、ユーザーに対して最新の商品名、価格、画像などを表示できます。
- **最新情報の保持**: 商品情報は変更される可能性があります。カートに`product_id`のみを保持しておくことで、ユーザーがカートを閲覧するたびに、最新の商品情報をデータベースから取得して表示することができます。
### 実装の例
商品情報の取得とカート表示の処理は、ビューやテンプレートで行われます。例えば、カートページを表示するビューでは、セッション内の`product_id`リストを元にデータベースから商品の詳細情報を取得し、それをテンプレートに渡して表示します。
このアプローチにより、ショッピングカートシステムは効率的かつ柔軟に商品情報を扱うことができます。カートに商品を追加する際に`product_id`のみを使用する理由は、このような背景に基づいています。
Djangoでのセッションは request.session にあり、辞書のように使えます。
>>> request.session['cart']
[1, 8]
cart_add 関数では以下のようにセッションの状態に応じて場合分けしています。
セッション内にすでに 'cart' がある場合には末尾に新しい product_id を追加
セッション内に 'cart' がない場合には追加された商品1つが入ったカート ([product_id]) で初期化
Tips
cart_add View関数は以下のようにも書けます。
.get(...) にデフォルト値を [] にして if 文を略しています。
def cart_add(request, product_id):
cart = request.session.get('cart', [])
cart.append(product_id)
request.session['cart'] = cart
return HttpResponseRedirect(reverse('product_list'))