Home > other >  How can show categories products in home page?
How can show categories products in home page?

Time:06-15

I want to show my all products row by row on the home page category-wise. Suppose, before starting a new row will have a heading(category name) and then will show all products according to the product category and then again will be starting a new row with a heading according to category. How can I do it? I applied the 3/4 methods but didn't work. Bellow, I've shown one of the methods. It doesn't work properly. Please help me.

views.py:

def home(request):
    all_products = Products.objects.all()

    context ={
        "all_products":all_products,
    }
    return render(request,'home.html', context)

model.py:

class Category(models.Model):
    title = models.CharField(blank=True, null=True, max_length = 100)

    def __str__(self):
        return str(self.title)

class Products(models.Model):
    product_image = models.ImageField(blank=True, null=True, upload_to = "1_products_img")
    product_title = models.CharField(blank=True, null=True, max_length = 250)
    product_price = models.IntegerField(blank=True, null=True)
    offer_price = models.IntegerField(blank=True, null=True)
    created_date = models.DateTimeField(blank=True, null=True, auto_now=True)


    product_category = models.ForeignKey(Category, related_name="categoty_related_name", on_delete=models.CASCADE, blank=True, null=True)

context_processors.py:

from .models import Category

def categories(request):
    return {"categories":Category.objects.all()}

template:

{% for products in all_products %}
<h4 >{{products.product_category}}</h4>
<hr>

<!--- product card --->

<div >
    <div >

        <!-- Sale badge-->
        {% if products.offer_price != None %}
        <div  style="top: 0.5rem; right: 0.5rem">
            SALE
        </div>
        {% endif %}

        <!-- Product image-->
        <img  style="height:150px;" src="{{products.product_image.url}}" alt="..." />
        <!-- Product details-->
        <div >
            <div >
                <!-- Product name-->
                <h5  style="">{{products.product_title}}</h5>

            </div>
        </div>

    </div>
</div>
{% endfor %}

CodePudding user response:

You have to change your thinking a bit :) The easiest approach is to think from bigger "items" (like your Category) to smaller (Product).

Firstfully, use singular naming for models, like Product (without 's', just like you did with Category), because otherwise you will end up with confusing setting. Also, don't name fields with your model's name unless it's really necessary, product_category should be simply category and so on.

Secondly, open big for loop with Category that you pass as classic view's context:

def home(request):
    categories = Category.objects.all()

    context = {
        "categories": categories,
    }
    return render(request,'home.html', context)

Then look at your ForeignKey field in Product:

class Products(models.Model):
    ...
    category = models.ForeignKey(Category, related_name="products", ...)

The key is to use related name properly. In your template, try logic like this (using related_name smoothly in reversed relationship):

{% for category in categories %}
    {{ category.title }}

    {% for product in category.products.all %}
        {{ product.title }} - {{ product.price }}
    {% endfor %}
{% endfor %}

If you don't set related_name, then it would be accessible with <model_name>_set.all(), in this case product_set.all() (in templates without brackets, of course). Anyway, it will work like a charm :)

  • Related