Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

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

とかで設定できるんではないか??

と思ったけど、答えは以下のとおりでした。

d.hatena.ne.jp

めちゃめちゃわかりやすい。

ある顧客が同じ商品を複数回購入した場合に、その事実をデータとして保持できない。 受注単位のデータ(受注日など)を保持できない。

カートと、商品だけしかないフィールドだったら、OKだけどその上、カートのユーザーまで絡んでくると、ユーザーと商品の関係が保存できない。