Как отфильтровать поле Many to Many на странице администратора django, используя значение внешнего ключа?
Я пытаюсь отфильтровать мои многие ко многим поля вариаций относительно продукта. то есть я хочу, чтобы только вариации, связанные с продуктом, отображались в админке. сейчас он показывает все вариации, доступные для каждого продукта.
Я добавил функцию formfield_for_manytomany() в свой admin.py, но как я могу получить текущий товар (id) в корзине или заказе для фильтрации вариантов?
Возможно, это просто, но я новичок в этой области!
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
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
Модель продукта и вариации
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