How to filter Many to Many field in django admin page using a foreign key value?

Viewed 44

I am trying to filter my many to many variation fields with respect to the product. means, I only want the variations related to the current product to show in the admin page. now its showing all the variations available for every product.

I added formfield_for_manytomany() function to my admin.py but how can I get the current product(id) in the cart or order to filter the variations?

most of the questions in stack overflow Is based on the current user, which is easy to get? but how should I get the specific product(id) that is opened in the admin panel.

admin.py

from django.contrib import admin
from .models import *
from products.models import Variation

class CartAdmin(admin.ModelAdmin):
  list_display = ('cart_id', 'date_created')

class CartItemAdmin(admin.ModelAdmin):
  list_display = ('user','cart', 'product', 'quantity','is_active')

  def formfield_for_manytomany(self, db_field, request, **kwargs):
      if db_field.name == "variation":

          product = Products.objects.get(id='??')  # how I get the current product in the cart or order

          kwargs["queryset"] = Variation.objects.filter(product=product.id)
      return super().formfield_for_manytomany(db_field, request, **kwargs)


admin.site.register(Cart, CartAdmin)
admin.site.register(CartItem, CartItemAdmin)

CartItem Model

class CartItem(models.Model):
  user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, null=True)
  cart = models.ForeignKey(Cart, on_delete=models.CASCADE, null=True)
  product = models.ForeignKey(Products, on_delete=models.CASCADE)
  variation = models.ManyToManyField(Variation, blank=True)
  quantity = models.IntegerField()
  is_active = models.BooleanField(default=True)
  created_date = models.DateTimeField(auto_now_add=True)

  def item_total(self):
    return self.product.price * self.quantity
    
  def __str__(self):
    return self.product.name

Product and Variation Model

class Products(models.Model):
  name = models.CharField(max_length=50, unique=True)
  slug = AutoSlugField(populate_from='name', max_length=100, unique=True)
  isbn = models.CharField(max_length=20, unique=True, blank=True, null=True)
  sub_category = models.ForeignKey(SubCategory, on_delete=models.CASCADE)
  language = models.ForeignKey(Language, on_delete=models.SET_NULL, null=True)

  author = models.CharField(max_length=100)
  Publisher = models.CharField(max_length=100, blank=True, default=None)
  release_date = models.DateField(blank=True, null=True, default=None)
  price = models.IntegerField(default=None)
  stock = models.IntegerField(default=None)
  is_available = models.BooleanField(default=True)

  cover_image = models.ImageField(upload_to='images/products')
  image1 = models.ImageField(upload_to='images/products', blank=True, default=None, null=True)
  image2 = models.ImageField(upload_to='images/products', blank=True, default=None, null=True)
  image3 = models.ImageField(upload_to='images/products', blank=True, default=None, null=True)

  description = models.TextField(max_length=2000, blank=True, default=None)
  create_date = models.DateTimeField(auto_now_add=True)
  modified_date = models.DateTimeField(auto_now=True)

  number_of_pages = models.IntegerField(blank=True, null=True)
  weight = models.IntegerField(blank=True, null=True)
  width = models.IntegerField(blank=True, null=True)
  height = models.IntegerField(blank=True, null=True)
  spine_width = models.IntegerField(blank=True, null=True)


  class Meta:
    verbose_name = 'Product'
    verbose_name_plural = 'Products'

  def get_url(self):
    return reverse('product-view', args=[self.slug])

  def __str__(self):
    return self.name


class Variation(models.Model):
  product = models.ForeignKey(Products, on_delete=models.CASCADE)
  variation_category = models.CharField(max_length=100, choices=variation_category_choice)
  variation_value = models.CharField(max_length=100, choices=variation_value_choice)
  is_available = models.BooleanField(default=True)  
  date_added = models.DateTimeField(auto_now_add=True)

  objects = VariationManager()

  def __str__(self):
    return self.variation_value
0 Answers
Related