I have a few categories and I would like to list the products per category
I have a few categories and I would like to list the products per category in the format below (categories is an FK to products):
Category 1
bunch of products
....
Category N
bunch of products
I have tried many ways but so far I only get the categories but not the products to show in my HTML.
I m new in django cant find the solution
in models.py:
from django.utils import timezone
from distutils.command.upload import upload
from email.policy import default
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Main_Category(models.Model):
name=models.CharField(max_length=100)
def __str__(self):
return self.name
class Sub_Category(models.Model):
main_category=models.ForeignKey(Main_Category,on_delete=models.CASCADE)
name=models.CharField(max_length=100)
def __str__(self):
return self.name
class Product(models.Model):
Status=('publish','publish'),('draft','draft')
product_id=models.AutoField
name=models.CharField(max_length=50)
category=models.ForeignKey(Main_Category,on_delete=models.CASCADE,null=True,default="")
sub_category=models.ForeignKey(Sub_Category,on_delete=models.CASCADE,null=True,default="")
price=models.IntegerField(default=0)
des=models.CharField(max_length=2000)
status=models.CharField(choices=Status,max_length=200)
delivery=models.IntegerField(null=True)
date=models.DateTimeField()
image=models.ImageField(upload_to="shop/images",default="Status")
slug=models.CharField(max_length=150)
def __str__(self):
return self.name
@property
def get_products(self):
return Product.objects.filter(categories__title=self.name)
class Orders(models.Model):
user=models.ForeignKey(User,on_delete=models.CASCADE)
amount=models.CharField(max_length=55)
Order_id=models.AutoField(primary_key=True)
name=models.CharField(max_length=55)
email=models.CharField(max_length=30)
address=models.CharField(max_length=200)
phone=models.CharField(max_length=15)
city=models.CharField(max_length=20)
state=models.CharField(max_length=20)
zip_code=models.CharField(max_length=10)
date=models.DateTimeField(default=timezone.now)
def __str__(self):
return self.user.username
class OrderItem(models.Model):
order=models.ForeignKey(Orders,on_delete=models.CASCADE)
product=models.CharField(max_length=200)
image=models.ImageField(upload_to="shop/images/cust_image")
quantity=models.CharField(max_length=20)
price=models.CharField(max_length=15)
total=models.CharField(max_length=1000)
def __str__(self):
return self.order.user.username
Views.py
from django.shortcuts import redirect, render
from .models import Main_Category, Product,Sub_Category,Orders,OrderItem
from django.core.paginator import Paginator
from django.contrib.auth.decorators import login_required
from cart.cart import Cart
from django.contrib.auth.models import User,auth
from django.contrib import messages
# Create your views here.
def index(request):
allproduct=Product.objects.all() ###filter(publish)which product you want to display in homepage
main_category=Main_Category.objects.all().order_by('-id')
categoryID = request.GET.get('main_category')
if categoryID:
allproduct=Product.objects.filter(sub_category=categoryID)
else:
allproduct=Product.objects.all()
paginator=Paginator(allproduct,5)
page_number=request.GET.get('page')
pagedata=paginator.get_page(page_number)
totalpage=pagedata.paginator.num_pages
print(allproduct)
context= {'allproduct':allproduct,
'main_category':main_category,
'allproduct':pagedata,
'totalpagelist':[n+1 for n in range(totalpage)]
}
return render (request,"shop/index.html",context)
in html:
<div class="col">
<div class="row ">
{% for product in allproduct %}
<div class="col-6 col-sm-6 col-md-6 col-lg-3">
<div class="card">
<img class="card-img-top " src='/media/{{product.image}}' alt="Card image cap">
<div class="card-body">
<h4 class="card-title">{{product.name}}</h4>
<p class="card-text">{{product.des |truncatechars:50}}</p>
<p class="card-text">{{product.time}}</p>
<div class="row">
<div class="col">
<a class=" btn btn-primary" href="{% url 'cart_add' product.id %}">Add to cart</a>
<a class="btn btn-danger ">{{product.price}} Tk</a>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
To do it, I think you should change the ForeignKey to a OnetoOneField in the Product class. Then you can access it from the Category and Sub_Category class.
But to do it with the current setup, you would have to go through each category and filter the products by it.
So…
categories = Category.objects.all()
list = []
for cat in categories:
products = Products.objects.filter_by(category=cat)
dics = {"name":cat, "products":products}
list.append(dics)
then return the variable list to the html template