Django e-commerce part37 ManyToMany Through
多対多フィールドのthroughを使って見る
carts/admin.py にcartを追加していく
from django.contrib import admin # Register your models here. from .models import Cart, CartItem class CartItemInline(admin.TabularInline): model = CartItem class CartAdmin(admin.ModelAdmin): inlines = [ CartItemInline ] class Meta: model = Cart admin.site.register(Cart, CartAdmin)
cartitemは、inlineで、cartadminに追加
thruough=cartitem を使って、cartとvariation を擬似的に多対多にする。
adminのinlineを設定するときは、cart, cartitemが紐づけられてないといけない。ただ、cart item, cartは、単純なforeignkeyでは結び付けられない。そこで登場するのが、多対多フィールドのthrough。これは、cartitemがcartとvariationの橋渡しになるような動作をする。
図にすると、以下のような流れになっている。
cart 1 → 多 cartitem 多 → 1variation
公式ドキュメントは以下の箇所:
モデル | Django documentation | Django
from django.conf import settings from django.db import models from products.models import Variation # Create your models here. class CartItem(models.Model): cart = models.ForeignKey("Cart") item = models.ForeignKey(Variation) quantity = models.PositiveIntegerField(default=1) #line item total def __str__(self): return self.item.title class Cart(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True) items = models.ManyToManyField(Variation, through=CartItem) timestamp = models.DateTimeField(auto_now=False, auto_now_add=True) updated = models.DateTimeField(auto_now=True, auto_now_add=False) def __str__(self): return str(self.id)
makemigrationすると、cartのdefault値を聞かれるので、1とかを入れておく。
問題点・課題など:多対多について
多対多の問題点は、1対多、1対1のフィールドと違って、関連を保持しておくことができないこと。 ただ、今回の場合は、カートとProductの1対多だとダメなのかがよくわからない。
例えば、商品とカートの例だと、商品1商品2 は、カート1、2、3 に紐付いてると ユーザー1 カート1 商品1、商品2 ユーザー2 カート2 商品2、商品3 ユーザー1 カート3 商品3、商品4
とかで設定できるんではないか??
と思ったけど、答えは以下のとおりでした。
めちゃめちゃわかりやすい。
ある顧客が同じ商品を複数回購入した場合に、その事実をデータとして保持できない。 受注単位のデータ(受注日など)を保持できない。
カートと、商品だけしかないフィールドだったら、OKだけどその上、カートのユーザーまで絡んでくると、ユーザーと商品の関係が保存できない。