In an online shop I use django-mptt
for product categories with several levels. I also have products that each belong to a category.
Now I'd like to visualise the category tree like this:
all(18)
- edible (10)
-- food (4)
-- drink (6)
- inedible (8)
-- wood (3)
-- rock (5)
where the numbers in scopes are the product counts for each category.
I am able to visualize the category tree. I can also place the product count behind the category names, but the way I am doing it seems very inefficient. I basically have a get_number_of_products()
methods at the category model which returns the number of products for a category. But this needs a new database query each time.
One way to deal with this is to use caching as I don't change the product count that often, but I'd prefer a method that needs less database queries to get the tree with the product count.
What you want is add_related_count
Category.objects.add_related_count(
Category.objects.get_descendants(include_self=True), # Queryset
Product, # Related mobile
'category', # Name of the foreignkey field
'count', # Name of the property added to the collection
cumulative=True) # Cumulative or not.
For instance in the admin you can use something like that:
class CategoryAdmin(DraggableMPTTAdmin):
mptt_indent_field = "name"
list_display = ('tree_actions', 'indented_title',
'related_products_count', 'related_products_cumulative_count')
list_display_links = ('indented_title',)
def get_queryset(self, request):
qs = super().get_queryset(request)
# Add cumulative product count
qs = Category.objects.add_related_count(
qs,
Product,
'category',
'products_cumulative_count',
cumulative=True)
# Add non cumulative recipe count
qs = Category.objects.add_related_count(qs,
Product,
'categories',
'products_count',
cumulative=False)
return qs
def related_products_count(self, instance):
return instance.products_count
related_product_count.short_description = 'Related products (for this specific category)'
def related_products_cumulative_count(self, instance):
return instance.products_cumulative_count
related_products_cumulative_count.short_description = 'Related products (in tree)'
My answer is connected to Django-Oscar, but you may find it out helpful
{{ for tree category in tree_categories }}
is a Category class, so it's possible get children by
{{ tree_category.get_num_children }}
来源:https://stackoverflow.com/questions/35717448/mptt-with-count-of-a-different-models-instances-that-have-tree-model-as-foreignk