Получение цвета продукта в цветовом фильтре по категории

Я пытаюсь получить товары определенной категории по слогу категории. У меня есть модель цвета, модель продукта и модель вариации продукта в приложении магазина.

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
Вернуться на верх