Получение цвета продукта в цветовом фильтре по категории
Я пытаюсь получить товары определенной категории по слогу категории. У меня есть модель цвета, модель продукта и модель вариации продукта в приложении магазина.
class Colour(models.Model):
title = models.CharField(max_length=100)
color_code = models.CharField(max_length=50,null=True)
class Product(models.Model):
product_name = models.CharField(max_length=100,unique=True)
slug = models.SlugField(max_length=100,unique=True)
content = RichTextUploadingField()
price = models.IntegerField()
images = models.ImageField(upload_to='photos/products')
is_available = models.BooleanField(default=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE,related_name="procat")
created_date = models.DateTimeField(auto_now_add=True)
modified_date = models.DateTimeField(auto_now=True)
is_featured = models.BooleanField()
class ProductVaraiant(models.Model):
product = models.ForeignKey(Product,on_delete=models.CASCADE)
color = models.ForeignKey(Colour,on_delete=models.CASCADE,blank=True, null=True)
size = models.ForeignKey(Size, on_delete=models.CASCADE,blank=True, null=True)
brand = models.ForeignKey(Brand,on_delete=models.CASCADE,blank=True, null=True)
amount_in_stock = models.IntegerField()
class Meta:
constraints = [
models.UniqueConstraint(
fields=['product', 'color', 'size','brand'],
name='unique_prod_color_size_combo'
В моем файле views.py,
def shop(request,category_slug=None):
categories = None
products = None
if category_slug != None:
categories = get_object_or_404(Category,slug = category_slug)
products = Product.objects.filter(category=categories,is_available=True).order_by('id')
variation = ProductVaraiant.objects.filter(product__category = categories)
print(variation)
# color = color.objects.all()
products_count = products.count()
else:
products = Product.objects.all().filter(is_available=True).order_by('id')
products_count = products.count()
variation = ProductVaraiant.objects.all()
print(variation)
context = {
'products' : products,
'products_count' : products_count,
'variation' : variation
}
return render(request,'shop/shop.html',context)
модель моей категории,
class Category(MPTTModel):
parent = TreeForeignKey('self',blank=True,null=True,related_name='children',on_delete=models.CASCADE)
category_name = models.CharField(max_length=200,unique=True)
category_img = models.ImageField(upload_to='photos/categories',blank=True)
slug = models.SlugField(max_length=100,unique=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def img_preview(self):
return mark_safe('<img src = "{url}" width = "50" height = "50"/>'.format(
url = self.category_img.url
))
def __str__(self):
return self.category_name
class Meta:
verbose_name_plural = 'categories'
class MPTTMeta:
order_insertion_by = ['category_name']
Что я пытаюсь получить, например, у меня есть 3 дочерние категории. Каждая категория будет иметь продукт любого цвета. Таким образом, если я фильтрую продукт по категории, цвет будет показан в боковой панели продуктов этой категории, не избегая получения дубликатов, так как многие продукты могут иметь тот же цвет. Таким образом, я получаю тот же цвет несколько раз. Если мне нужно использовать distinct(), как использовать его в запросе, который будет удалять дубликаты цвета на основе категории продукта. Я пробовал это в шаблоне
<form>
<div class="custom-control custom-checkbox d-flex align-items-center justify-content-between mb-3">
<input type="checkbox" class="custom-control-input" checked id="color-all">
<label class="custom-control-label" for="price-all">All Color</label>
<span class="badge border font-weight-normal">1000</span>
</div>
{% for i in variation %}
{% ifchanged i.color %}
<div class="custom-control custom-checkbox d-flex align-items-center justify-content-between mb-3">
<input type="checkbox" class="custom-control-input filter-checkbox" id="{{i.color.id}}" data-filter="color">
<label class="custom-control-label" for="{{i.color.id}}">{{i.color}}</label>
<span class="badge border font-weight-normal">150</span>
</div>
{% endifchanged %}
{% endfor %}
</form>
Но, он просто удаляет дубликат последней итерации. Как избежать получения дубликатов для всех цветов?
Там, где у вас есть линия
# color = color.objects.all()
измените ее на color = products.color.all().distinct('id')
и затем передайте ее вашему шаблону.
Ответ на мою проблему, что я сделал:
variation = ProductVaraiant.objects.filter(product__category = categories)
что я изменил:
variation = ProductVaraiant.objects.filter(product__category=categories).values('color__title').distinct()
если используется база данных postgre, не нужно использовать значения, просто используйте distinct('color') и вам нужно будет использовать значения для базы данных по умолчанию, чтобы избежать ошибки ниже,
DISTINCT ON fields is not supported by this database backend