0

So I have a product Model which say looks like this :

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

and I also have a cart model which looks like this :

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

the thing is I want to add a quantity field to the product so the user can add multiple products from the same product in the cart But I only want it when the product is in a cart (I don't want to add it in the ProductModel) Instead I want to add it to the product fields in the many to many relationship. I've done a bit of research and most of the answers aren't clear enough on how I should be doing this.

1 Answers1

1

You can create new fields in the intermediate relation table between Products and Cart. You have to define a new class for this intermediate table and to use it with the through attribute of the M2M field.

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 ' '

One way for displaying it in the admin can be to use TabularInline for the products of the cart:

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)
acg
  • 188
  • 6
  • I tried this but it gives me the following error : Cannot alter field homepage.CartModel.products into homepage.CartModel.products - they are not compatible types (you cannot alter to or from M2M fields, or add or remove through= on M2M fields) – Ahmed Mohsen Nov 20 '20 at 16:23
  • 1
    Sometimes after some complex changes in the models, Django can't create the proper migration file. Try to follow the steps of this post to solve it [link](https://stackoverflow.com/a/51351406/10780476). – acg Nov 20 '20 at 16:41
  • Ok I will try It and Inform you after I do, Thanks for the help. – Ahmed Mohsen Nov 21 '20 at 16:20
  • I did what you said and it works. But the thing is it looks ugly on the admin page, because every single product in the cart appears as an object in the ProductCart model. So if there is multiple users it will be a mess. What I really want is that I can access the products and the specs of them through the cart model (If that's possible) – Ahmed Mohsen Nov 23 '20 at 19:14
  • I updated the answer for displaying the products from the cart it in the admin – acg Nov 23 '20 at 20:06
  • Wow, That did it perfectly, thanks for the help, I really appreciate it. – Ahmed Mohsen Nov 24 '20 at 15:19