Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

283
Visualizações
Recuento inverso de ManytoManyField con una condición

Tengo un caso de uso en el que tengo que contar las ocurrencias de ManyToManyField, pero se está volviendo más complejo de lo que pensaba.

modelos.py :

 class Tag(models.Model): name = models.CharField(max_length=100, unique=True) class People(models.Model): tag = models.ManyToManyField(Tag, blank=True)

Aquí tengo que crear una lista de Tags y la cantidad de veces que aparecen en general, pero solo para aquellas People que tienen> 0 y <6 etiquetas. Algo como:

 tag1 - 265338 tag2 - 4649303 tag3 - 36636 ...

Así es como se me ocurrió el conteo inicialmente:

 q = People.objects.annotate(tag_count=Count('tag')).filter(tag_count__lte=6, tag_count__gt=0) for tag in Tag.objects.all(): cnt = q.filter(tag__name=tag.name).count() # doing something with the cnt

Pero luego me di cuenta de que esto puede ser ineficiente ya que probablemente estoy iterando a través del modelo People muchas veces (los registros en People son mucho más grandes que los de Tag).

Intuitivamente, creo que debería poder hacer una iteración del modelo Tag sin ninguna iteración del modelo People . Entonces se me ocurrió esto:

 for tag in Tag.objects.all(): cnt = tag.people_set.annotate(tag_count=Count('tag')).filter(tag_count__lte=6).count() # doing something with the cnt

Pero, en primer lugar, esto no está dando los resultados esperados. En segundo lugar, estoy pensando que esto se ha vuelto más complejo de lo que parecía ser, así que quizás esté complicando algo simple. Todos los oídos a cualquier consejo.

Actualización: obtuve queryset.query y ejecuté la consulta en la base de datos para depurarla. Por alguna razón, la columna tag_count en la combinación resultante muestra todos los 1. Parece que no puedo entender por qué.

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Se puede hacer usando la consulta de campo inversa ManyToMany.

También reduciría la sobrecarga y cambiaría la mayor parte de la sobrecarga de python al servidor de la base de datos.

 from some_app.models import Tag, People from django.db.models import F, Value, Count, CharField from django.db.models.functions import Concat # queryset: people with tags >0 and <6, ie 1 to 5 tags people_qualified = People.objects.annotate(tag_count=Count('tag'))\ .filter(tag_count__range=(1, 5)) # query tags used with above category of people, with count tag_usage = Tag.objects.filter(people__in=people_qualified)\ .annotate(tag=F('name'), count=Count('people'))\ .values('tag', 'count') # Result: <QuerySet [{'count': 3, 'tag': u'hello'}, {'count': 2, 'tag': u'world'}]> # similarily, if needed the string output tag_usage_list = Tag.objects.filter(people__in=people_qualified)\ .annotate(tags=Concat(F('name'), Value(' - '), Count('people'), output_field=CharField()))\ .values_list('tags', flat=True) # Result: <QuerySet [u'hello - 3', u'world - 2']>
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda