Home > Enterprise >  Get product color in color filter by Category wise
Get product color in color filter by Category wise

Time:12-03

I am trying to get a specific category products by category slug.I have Color model,Product model and product variation model in shop app.

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'

In my 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)

my category model,

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

what i am trying to get is like i have 3 child category..Each category will have product of any color.So,if i filter product by category,color will be shown in sidebar of that category products without avoid getting duplicates as many product may have same color.So,i am getting same color multiple times.If i need to use distinct(),how to use it in query that will remove duplicate color based on product category.I tried this in template


                <form>
                    <div >
                        <input type="checkbox"  checked id="color-all">
                        <label  for="price-all">All Color</label>
                        <span >1000</span>
                    </div>
                    {% for i in variation %}
                    {% ifchanged i.color %}
                    <div >
                        <input type="checkbox"  id="{{i.color.id}}" data-filter="color">
                        <label  for="{{i.color.id}}">{{i.color}}</label>
                        <span >150</span>
                    </div>
                    {% endifchanged %}
                    {% endfor %}
                </form>

But,it just remove duplicate of last iteration.How to avoid getting duplicates for all color?

CodePudding user response:

Just where you have a line # color = color.objects.all() change it to color = variation.color.all().distinct('id') and then pass it to your template.

CodePudding user response:

Answer of my problem, what i did:

variation = ProductVaraiant.objects.filter(product__category = categories)

what i changed:

variation = ProductVaraiant.objects.filter(product__category=categories).values('color__title').distinct()

if using postgre database,don't need to use values,just use distinct('color') and you will need to use values for default database to avoid error below,

DISTINCT ON fields is not supported by this database backend
  • Related