I wanna be able to search a product with the category that isnt directly linked to it but the category is grandfather or great_great grandfather and so on above on the category tree of the category that is actually linked to the product itself. The only way i could implement was with the following which is ofcourse not scalable and proper way to do it:
def get_queryset(self, request):
queryset = super().get_queryset(request).select_related('brand', 'category', 'category__parent')
category_name = request.GET.get('category__name', None)
if category_name:
# Filter the queryset to include products with the specified category or its ancestors
queryset = queryset.filter(
Q(category__name=category_name) |
Q(category__parent__name=category_name) |
Q(category__parent__parent__name=category_name) |
# Add more levels as needed based on the depth of your category tree
)
return queryset
And here are the code as of now:
Product``models.py
class Product(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(blank=True, null=True)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
image = models.ImageField(upload_to='product_images/')
category = models.ForeignKey(Category, on_delete=models.SET_NULL,related_name='product_category', null=True, blank=True)
brand = models.ForeignKey(Brand, on_delete=models.SET_NULL, related_name='product_brand', null=True, blank=True)
tags = GenericRelation(TaggedItem, related_query_name='product')
ratings = GenericRelation(Rating, related_query_name='product')
active = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
state = models.CharField(max_length=2, choices=PublishStateOptions.choices, default=PublishStateOptions.DRAFT)
publish_timestamp = models.DateTimeField(
# means that the publish_timestamp field will not automatically be set to the current date and time when a new instance of this model is created.
auto_now_add=False,
# means that the publish_timestamp field will not automatically be updated to the current date and time every time the model is saved.
auto_now=False,
blank=True,
null=True
)
def __str__(self):
return self.name
Category``models.py
class Category(models.Model):
name = models.CharField(max_length=255)
parent = models.ForeignKey('self', on_delete=models.SET_NULL, related_name='subcategories', null=True, blank=True)
class Meta:
verbose_name_plural = 'Categories'
def __str__(self):
return self.name
Product``admin.py
class ProductAdmin(admin.ModelAdmin):
list_display = ['name', 'price', 'brand', 'category']
inlines = [TaggedItemInline]
list_filter = [
'brand__name',
'category__name'
]
search_fields = ['name', 'price', 'brand__name', 'category__name', 'category__parent__name']
def get_queryset(self, request):
return super().get_queryset(request).select_related('brand', 'category', 'category__parent')
def get_brand_name(self, obj):
return obj.brand.name if obj.brand else None
def get_category_name(self, obj):
return obj.category.name if obj.category else None
get_brand_name.short_description = 'Brand'
get_category_name.short_description = 'Category'
# Define the labels for list filters
list_filter = (
('brand', admin.RelatedOnlyFieldListFilter),
('category', admin.RelatedOnlyFieldListFilter),
)
admin.site.register(Product, ProductAdmin)