Home > Mobile >  Django - count number of inline elements in class based view
Django - count number of inline elements in class based view

Time:08-19

I have 2 models: Product and ProductComponent. How can I count the number of components in each product so when I want to loop products in the template it will give me the title and the number of components per product?

class ProductComponent(models.Model):
    name = models.CharField(max_length=255)
    related_product = models.ForeignKey(Product, on_delete=models.CASCADE')
    
    @property
    def count_components(self):
        return self.component_name.count()

class Product(models.Model):
    title = models.CharField(max_length=400)

views.py

class TestView(ListView):
    template_name = "test.html"
    model = Product

    def get_context_data(self, **kwargs):
        context = super(TestView, self).get_context_data(**kwargs)
        context['product_list'] = Product.objects.filter(?)
        return context

I managed to do something like this in admin but only in the ProductComponent admin page but not in the Product admin page.

admin.py

class TestViewAdmin(ImportExportModelAdmin):
resource_class = TestViewAdminResource
list_display = ('get_component_count',)

def get_component_count(self, obj):
    return obj.related_product.related_product.count()

What I want to do is to create a loop of products with a number of components that are related to this product.

{% for product in product_list %}
    {{product.title}} - {{product.count_components}}
{% endfor %}

I'd appreciate any advice on how to achieve something like that.

CodePudding user response:

you can use the reverse lookup with using related_name on your ForeignKey or if not specified appending '_set' to your related model name:

{{ product.productcomponent_set.count }}

I recommend using related_name parameter on your ForeignKeys though as it makes cleaner and more descriptive code when in some more complicated relationships:

related_product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='components')

then you access it like:

{{ product.components.count }}

More info about backward relationships in Django Docs

  • Related