alesdario
alesdario

Reputation: 1894

Django filter objects by some referencing condition

In Django i have two models, Cateogory and Product, Product references Category in this way.

class Category(models.Model):
    name = models.CharField(max_length=255)

class Product(models.Model):
    category = models.ForeignKey(Category, null=True)

I want to obtain all Category which are at least referenced by one product.

I've obtained my goal with this solution:

class Category(models.Model):
        name = models.CharField(max_length=255)

        def has_product(self):
             products = self.product_set.all()
             if(len(products) > 0):
                   return True
             else:
                   return False

category_list = []

for cat in Category.objects.all(): 
        if cat.has_products():
             category_list.append(cat)

Are there any smarter solutions?

Upvotes: 0

Views: 185

Answers (2)

Pavel Anossov
Pavel Anossov

Reputation: 62868

You can do it with a list comprehension:

cats_with_prod = [c for c in Category.objects.all() if c.product_set.exists()]

But you can do it entirely in DB, in one query:

cats_with_prod = Category.objects.filter(product_set__isnull=False).distinct()

Upvotes: 2

mVChr
mVChr

Reputation: 50177

It looks like you can do it with a single list comprehension:

cats_with_prod = [c for c in Category.objects.all() if c.product_set.exists()]

Upvotes: 2

Related Questions