I'm trying to create a search bar where user can choose Category and write product name. So I can display all products in that category where the name of product matches with what he wrote in text input.
So I have Category
-> Subcategory
-> Product
. Is there any way to get Category object from Product model? (I don't have field for category in product model)
Here is my models.py
file:
# models.py
class Category(models.Model):
name = models.CharField(max_length=100, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'Categories'
def __str__(self):
return self.name
class Subcategory(models.Model):
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, related_name='subcategories')
name = models.CharField(max_length=200, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
top5 = models.BooleanField(default=False, null=True, blank=True)
featured = models.BooleanField(default=False, null=True, blank=True)
class Meta:
verbose_name_plural = 'Subcategories'
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=200, null=True, blank=True)
subcategory = models.ForeignKey(Subcategory, on_delete=models.SET_NULL, null=True, related_name='products')
image = models.ImageField(null=True, blank=True, upload_to='products/')
price_old = models.DecimalField(decimal_places=2, max_digits=7, null=True, blank=True)
price_new = models.DecimalField(decimal_places=2, max_digits=7, null=True, blank=True)
description = models.TextField()
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
# @property
# def category(self):
# return self.subcategory.category
Here as you can see I tried to create a property to get the category, but now I'm struggling to filter products that share the same category
Here is my views.py file:
def search_products(request):
q = request.GET.get('q') if request.GET.get('q') != None else ''
category = Category.objects.get(name=request.GET['category'])
products = Product.objects.filter(name__icontains=q, category=category) <-- This line
context = {'products':products, 'q':q}
return render(request, 'search_products.html', context)
If you have any ideas, I would be really glad to hear you!
Yes. Since your Product
model have a foreign key to Subcategory
, and Subcategory
has a foreign key to Category
, you can do the following in your template:
{% for product in products %}
Category: {{ product.subcategory.category }}
Product: {{ product }}</div>
{% endfor %}
To filter them, you should use the double underscore (__
) syntax:
products = Product.objects.filter(
name__icontains=q,
subcategory__category=category
)