I use django-mptt for Category model and I have Service model as well.
The problem:
- I got all services associated to node category by clicking on a child category.
What I want:
- I want to get all services associated to child category that I click. I believe I have to check it in an additional step in views (ServiceByCategoryListView). But I have no idea how to do that. Google doesn’t help me.
models.py
class Service(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(max_length=255)
description = models.TextField()
preparation = models.TextField()
price = models.CharField(max_length=10)
available = models.BooleanField(default='True')
category = TreeForeignKey('Category', on_delete=models.PROTECT, related_name='services')
def __str__(self):
return self.name
class Category(MPTTModel):
name = models.CharField(max_length=255, unique=True)
parent = TreeForeignKey('self',
on_delete=models.PROTECT,
null=True,
blank=True,
related_name='children',
db_index=True)
slug = models.SlugField()
class MPTTMeta:
order_insertion_by = ['name']
class Meta:
unique_together = [['parent', 'slug']]
def get_absolute_url(self):
return reverse('services-by-category', kwargs={'slug': self.slug})
urls.py
urlpatterns = [
path('', CategoryListView.as_view(), name='category-list'),
path('<slug:slug>/', ServiceByCategoryListView.as_view(), name='services-by-category'),
]
views.py
class CategoryListView(ListView):
model = Category
template_name = 'main/category_list.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['services'] = Service.objects.all()
return context
class ServiceByCategoryListView(ListView):
model = Service
context_object_name = 'services'
template_name = 'main/service_list.html'
def get_queryset(self):
self.category = Category.objects.filter(parent=None).get(slug=self.kwargs['slug'])
branch_categories = self.category.get_descendants(include_self=True)
queryset = Service.objects.filter(category__in=branch_categories)
return queryset
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['name'] = self.category
return context
I tried to find a solution in django-mptt documentation but have no result. Also I tried to use Q objects but I was not able to find a correct solution as well.
I'm not sure if I've understood the problem correctly, but if you want to have all the services associated with the child category you're clicking on, without the services of the category you're clicking on, you need to set include_self=False in the get_queryset of your ServiceByCategoryListView class.