【问题标题】:How to add an extra field for an existing model in case of many to many relationships in django在 django 中存在多对多关系的情况下,如何为现有模型添加额外字段
【发布时间】:2021-03-03 22:14:32
【问题描述】:

所以我有一个产品模型,它看起来像这样:

class ProductModel(models.Model):
    name = models.CharField(max_length=200)
    price = models.DecimalField(max_digits=6, decimal_places=2, null=True)

我还有一个看起来像这样的购物车模型:

class CartModel(models.Model):
    customer = models.ForeignKey(User, on_delete= models.CASCADE, related_name="cart")
    products = models.ManyToManyField(ProductModel)

问题是我想在产品中添加一个数量字段,以便用户可以从购物车中的同一产品中添加多个产品但我只想要产品在购物车中时(我不想添加它在 ProductModel 中)相反,我想将它添加到多对多关系中的产品字段中。我做了一些研究,大多数答案都不够清楚我应该如何做到这一点。

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    您可以在 Products 和 Cart 之间的中间关系表中创建新字段。您必须为这个中间表定义一个新类,并将其与 M2M 字段的 through 属性一起使用。

    from django.db import models
    from django.contrib.auth.models import User
    
    
    class ProductModel(models.Model):
        name = models.CharField(max_length=200)
        price = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    
        def __str__(self):
            return self.name
    
        class Meta:
            verbose_name = "Product"
    
    
    class CartModel(models.Model):
        customer = models.ForeignKey(User, on_delete=models.CASCADE, related_name="cart")
        products = models.ManyToManyField(ProductModel, through='ProductCart')
    
        def __str__(self):
            return "Cart nº {} - {}".format(self.pk, self.customer)
    
        class Meta:
            verbose_name = "Cart"
    
    
    class ProductCart(models.Model):
        product = models.ForeignKey(ProductModel, on_delete=models.CASCADE)
        cart = models.ForeignKey(CartModel, on_delete=models.CASCADE)
        quantity = models.IntegerField()
    
        def __str__(self):
            return ' '
    

    在管理员中显示它的一种方法是对购物车的产品使用 TabularInline:

    from django.contrib import admin
    from .models import CartModel
    
    
    class ProductsInline(admin.TabularInline):
        model = CartModel.products.through
        extra = 0
        exclude = ()
        verbose_name = 'Product'
    
    
    class CartAdmin(admin.ModelAdmin):
        list_display = ('customer',)
        list_filter = ('customer',)
        inlines = [
            ProductsInline,
        ]
    
    
    admin.site.register(CartModel, CartAdmin)
    

    【讨论】:

    • 我试过了,但它给了我以下错误:无法将字段 homepage.CartModel.products 更改为 homepage.CartModel.products - 它们不是兼容的类型(您不能更改 M2M 字段或从 M2M 字段更改)通过 = 在 M2M 字段上添加或删除)
    • 有时在模型中进行一些复杂的更改后,Django 无法创建正确的迁移文件。尝试按照本帖步骤解决link.
    • 好的,我会试试看,我会告诉你,谢谢你的帮助。
    • 我按照你说的做了,而且效果很好。但问题是它在管理页面上看起来很难看,因为购物车中的每个产品都在 ProductCart 模型中显示为一个对象。因此,如果有多个用户,那将是一团糟。我真正想要的是我可以通过购物车模型访问产品及其规格(如果可能的话)
    • 我更新了在管理员中显示购物车中产品的答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-02
    相关资源
    最近更新 更多