为django电子商务购物车使用多个模型

为django电子商务购物车使用多个模型,django,django-models,cart,Django,Django Models,Cart,我正在为我正在进行的一个电子商务项目制作一个购物车,目前购物车确实可以工作。然而,它只适用于一个模型,我不知道如何使它适用于多个模型 这是我的购物车文件夹中的my contexts.py文件: from django.shortcuts import get_object_or_404 from courses.models import Course from food_order.models import Food_order def cart_contents(request):

我正在为我正在进行的一个电子商务项目制作一个购物车,目前购物车确实可以工作。然而,它只适用于一个模型,我不知道如何使它适用于多个模型

这是我的购物车文件夹中的my contexts.py文件:

from django.shortcuts import get_object_or_404
from courses.models import Course
from food_order.models import Food_order


def cart_contents(request):
    """
    Ensures that the cart contents are available when rendering
    every page
    """
    cart = request.session.get('cart', {})

    cart_items = []
    total = 0
    course_count = 0

    for id, quantity in cart.items():
        course = get_object_or_404(Course, pk=id)
        total += quantity * course.price
        course_count += quantity
        cart_items.append({'id': id, 'quantity': quantity, 'course': course})

    return {'cart_items': cart_items, 'total': total, 'course_count': course_count}
这是我的观点

from django.shortcuts import render, redirect, reverse

# Create your views here.
def view_cart(request):
    """A View that renders the cart contents page"""
    return render(request, "cart.html")


def add_to_cart(request, id):
    """Add a quantity of the specified product to the cart"""
    quantity = int(request.POST.get('quantity'))

    cart = request.session.get('cart', {})
    if id in cart:
        cart[id] = int(cart[id]) + quantity      
    else:
        cart[id] = cart.get(id, quantity) 

    request.session['cart'] = cart
    return redirect(reverse('index'))


def adjust_cart(request, id):
    """
    Adjust the quantity of the specified product to the specified
    amount
    """
    quantity = int(request.POST.get('quantity'))
    cart = request.session.get('cart', {})

    if quantity > 0:
        cart[id] = quantity
    else:
        cart.pop(id)

    request.session['cart'] = cart
    return redirect(reverse('view_cart'))
所以我有两个不同的类,我想能够添加到购物车从2个不同的地方在电子商务网站上。我只是不知道怎样才能做到这一点

如果我做了以下事情:

from django.shortcuts import get_object_or_404
from courses.models import Course
from food_order.models import Food_order


def cart_contents(request):
    """
    Ensures that the cart contents are available when rendering
    every page
    """
    cart = request.session.get('cart', {})

    cart_items = []
    total_food_order = 0
    total_course = 0
    total = 0
    product_count = 0

    for id, quantity in cart.items():
        course = get_object_or_404(Course, pk=id)
        food_order = get_object_or_404(Food_order, pk=id)
        total_course += quantity * course.price
        total_food_order += quantity * food_order.price
        product_count += quantity
        cart_items.append({'id': id, 'quantity': quantity, 'course': course, 'food_order':food_order})

    total = total_course + total_food_order
    return {'cart_items': cart_items, 'total': total, 'product_count': product_count}
然后生成的
购物车项目将是:

[{'id': '1', 'quantity': 1, 'course': <Course: Basic Order Taking>, 'food_order': <Food_order: Onions>}, {'id': '2', 'quantity': 3, 'course': <Course: Advanced Order Taking>, 'food_order': <Food_order: Peppers>}]
[{'id':'1','quantity':1','course':,'food_order':},{'id':'2','quantity':3','course':,'food_order':}]
我理解它为什么这样做,但我想不出一种方法来调整我的代码以获得期望的结果。任何指点都将不胜感激


谢谢您的时间。

我建议为所有需要添加到购物车的模型制作一个基础模型,并使用多表继承

class BaseCartItem(models.Model):
    price = models.DecimalField()
    item_type = models.CharField(max_length=20, editable_false)
    ....

    def save(*args, **kwargs):
        self.item_type = self._get_item_type()
        return super().save(*args, **kwargs)

    def _get_item_type(self):
        raise NotImplementedError


class Course(BaseCartItem):
    ....

    def _get_item_type(self):
        return "Course"

class FoodOrder(BaseCartItem):
    ....

    def _get_item_type(self):
        return "Food Order"


#  if you want to add to the db
class Cart(models.Model)
    item = models.ForeignKey(BaseCartItem, on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField()
    ....
在视图中,一切都保持不变。您只需要使用基本模型的ID,而不是子模型的ID

购物车的内容简化了一点

def cart_contents(request):
    """
    Ensures that the cart contents are available when rendering
    every page
    """
    cart = request.session.get('cart', {})

    cart_items = []
    item_groups = defaultdict(int)
    total = 0
    product_count = 0

    items_map = {
        item.id: item
        for item in BaseCartItem.objects.filter(id__in=cart.keys()
    }

    for id, quantity in cart.items():
        item = items_map[id]
        item_group[item.item_type] += quantity * item.price
        product_count += quantity
        cart_items.append({'id': id, 'quantity': quantity, 'course': item, 'food_order':item})

    total = sum(item_groups.values())
    return {'cart_items': cart_items, 'total': total, 'product_count': product_count}

我建议为所有需要添加到购物车的模型创建一个基础模型,并使用多表继承

class BaseCartItem(models.Model):
    price = models.DecimalField()
    item_type = models.CharField(max_length=20, editable_false)
    ....

    def save(*args, **kwargs):
        self.item_type = self._get_item_type()
        return super().save(*args, **kwargs)

    def _get_item_type(self):
        raise NotImplementedError


class Course(BaseCartItem):
    ....

    def _get_item_type(self):
        return "Course"

class FoodOrder(BaseCartItem):
    ....

    def _get_item_type(self):
        return "Food Order"


#  if you want to add to the db
class Cart(models.Model)
    item = models.ForeignKey(BaseCartItem, on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField()
    ....
在视图中,一切都保持不变。您只需要使用基本模型的ID,而不是子模型的ID

购物车的内容简化了一点

def cart_contents(request):
    """
    Ensures that the cart contents are available when rendering
    every page
    """
    cart = request.session.get('cart', {})

    cart_items = []
    item_groups = defaultdict(int)
    total = 0
    product_count = 0

    items_map = {
        item.id: item
        for item in BaseCartItem.objects.filter(id__in=cart.keys()
    }

    for id, quantity in cart.items():
        item = items_map[id]
        item_group[item.item_type] += quantity * item.price
        product_count += quantity
        cart_items.append({'id': id, 'quantity': quantity, 'course': item, 'food_order':item})

    total = sum(item_groups.values())
    return {'cart_items': cart_items, 'total': total, 'product_count': product_count}

谢谢你的回复!我大体上听你说的。对于
BaseCartItem
,它会去哪里。我制作的每个模型都存在于将要使用它的文件夹中。i、 e食品订单位于Food\u order/models.py中。我会在顶层制作一个新的models.py吗?啊。。。也许如果你有一个通用的应用程序,你可以把它放在那个。。。通常你会把类似的东西放在一起。我假设每个应用程序都有很多与每个模型相关的逻辑,所以最好有一个带有通用逻辑的通用应用程序谢谢您的回复!我大体上听你说的。对于
BaseCartItem
,它会去哪里。我制作的每个模型都存在于将要使用它的文件夹中。i、 e食品订单位于Food\u order/models.py中。我会在顶层制作一个新的models.py吗?啊。。。也许如果你有一个通用的应用程序,你可以把它放在那个。。。通常你会把类似的东西放在一起。我假设每个应用程序都有很多与每个模型相关的逻辑,所以最好有一个具有公共逻辑的公共应用程序