0

I have 2 model classes called product and product_category

class product_category(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, on_delete=models.CASCADE)
    category_name = models.CharField(max_length=20, blank=False, null=False, default="")
    slug = models.SlugField(max_length=255, unique=True)


class product(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, on_delete=models.CASCADE)
    product_name = models.CharField(max_length=50, blank=False, null=False, default="")
    product_description = models.TextField(max_length=280, blank=True, null=True, default="")
    product_type = models.ForeignKey(product_category, related_name='type_category', blank=True, null=True, on_delete=models.CASCADE)
    slug = models.SlugField(max_length=255, unique=True)


In the views.py this is how I usually load all the products related to a single user

all_category = product.objects.filter(user=user)

but what I am struggling to filter is the product list based on the category they are in.

As you can see, product_type is optional, so some products might not have any type. Those products should be listed at the end of the list.

This is how I want to display it on the website

  • category-1
    • product-1
    • product-2
    • product-3
  • category-2
    • product-4
    • product-5
    • product-6
  • category-3
    • product-7
  • product-8
  • product-9
  • product-10

how can I achieve this?

EDIT 1.

Thanks to neeraj-kumar, I found what I was looking for.

here's his answer with a bit of
in the code to see the result more clearly.

views.py

    all_category = product_category.objects.filter(user=user)
    product_exclude = product.objects.exclude(id__in=all_category.values_list('type_category__id',flat=True)).filter(user=user)

template.html

{% for cat in all_category %}
    {% with products=cat.type_category.all %}
        <h5>{{cat.category_name}}</h5>
        {% if products|length %}
            {% for pro in products %}
                <p>{{ pro }}</p>
            {% endfor %}
        {% endif %}
        <br>
    {% endwith %}
{% endfor %}
{% for pro in product_exclude %}
    <p>{{ pro }}</p>
{% endfor %}
Ali
  • 15
  • 1
  • 5

1 Answers1

0
all_category = product_category.objects.filter(user=user)
product_exclude = product.objects.exclude(id__in=all_category.values_list('type_category__id',flat=True)

pass both var in template

{% for cat in all_category %}
   {% with products = cat.type_category.all %}
       {% if products|length %}
            {% for pro in products %}
                {{ pro }}
            {% endfor %}
       {% endif %}
   {% endwith %}
{% endfor %}
{% for pro in product_exclude %}
     {{ pro }}
{% endfor %}
Neeraj Kumar
  • 3,851
  • 2
  • 19
  • 41
  • hey, I found a bug in this... if there are 4 categories, and if only 3 (or less) category have any product in them, it is not filtering product_exclude... i.e. product_exclude is empty, even if there are many products with no category... how do can we solve this? – Ali Mar 07 '18 at 12:06
  • It's not working for some reason. I feel the problem is in .exclude(). Because when I am replacing .exclude with .filter, it is showing a list of items which we want to be excluded. How can we get rid of this bug? any Idea? – Ali Mar 07 '18 at 13:15