Daniel Aron Goldenberg
Daniel Aron Goldenberg

Reputation: 164

Django - Annotate with count across ManytoMany relationships (refrase)

Django - Annotate with count across ManytoMany relationships

I am not able to find the way to annotate a queryset with a count of how many times an element is used in a many-to-many relationship.

class Profile(models.Model):
    [...]
    # Profile can have multiple roles
    roles = models.ManyToManyField('Role', blank=True)
    [...]

class Role(models.Model):
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    name = models.CharField(blank=True, max_length=30)
    description = models.CharField(blank=True, max_length=300)
    [...] 

For example I would have 5 roles:

And 2 profiles with following roles assigned:

I need to have the oposite than @ha-duy:

Profile: name, role_count=2
Profile: name, role_count=3

Any ideas?

Thanks!

Upvotes: 0

Views: 89

Answers (1)

CR Python
CR Python

Reputation: 146

One Idea:

In the same view where you update the rolls loop through the many to many fields and return the length. then update the model appropriately.

Better Idea:

create a custom save method for the profile model so that every time .save() is called it will calculate the number of roles and update that field. more info on that here. custom save method on model - django

Maybe this will help because it won't be persistent in the DB but will give you the info:

class Test(models.Model):
name = models.CharField(max_length=10,)
category = models.ManyToManyField(cats)

def __str__(self):
    x = self.category.all()
    y = len(x) 
    return 'this is an item count ' + str(y)

or if you want it in object form:

add this to the model.

    def dataBlock(self):
       x = self.category.all()
       y = len(x) 
       return {
           'name': self.name,
           'cat_length': y,
       }

Upvotes: 1

Related Questions