Django: anota con conteo en las relaciones ManytoMany

No puedo encontrar la manera de anotar un conjunto de consultas con un recuento de cuántas veces se usa un elemento en una relación de muchos a muchos.

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)
    [...] 

Por ejemplo, tendría 5 roles:

  • Rol1
  • Rol2
  • Rol3
  • Rol4
  • Rol5

Y 2 perfiles con los siguientes roles asignados:

  • Perfil1
    • Función 1
    • Función 2
  • Perfil2
    • Función 1
    • Función 3
    • Función 4

Necesito tener lo opuesto a @ ha-duy:

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

¿Alguna idea?

¡Gracias!

0
Daniel Aron Goldenberg 16 nov. 2019 a las 23:08

1 respuesta

La mejor respuesta

Una idea:

En la misma vista, donde actualiza los rollos, recorre los campos de muchos a muchos y devuelve la longitud. luego actualice el modelo apropiadamente.

Mejor idea:

Cree un método de guardado personalizado para el modelo de perfil de modo que cada vez que se llame a .save () calcule el número de roles y actualice ese campo. más información sobre eso aquí. método de guardado personalizado en el modelo: django

Tal vez esto ayude porque no será persistente en la base de datos, pero le dará la información:

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)

O si lo quieres en forma de objeto:

Agregue esto al modelo.

    def dataBlock(self):
       x = self.category.all()
       y = len(x) 
       return {
           'name': self.name,
           'cat_length': y,
       }
1
CR Python 17 nov. 2019 a las 01:16