Estoy intentando crear una página de perfil que muestra la cantidad de enanos asignados a cada carrera correspondiente. Tengo 4 carreras, 2 trabajos dentro de cada una de esas carreras y, por supuesto, muchos enanos que tienen un solo trabajo. ¿Cómo puedo contar el número de enanos en cada una de esas carreras? Mi solución fue hacer un seguimiento de los nombres de las carreras en el HTML y hacer una consulta para cada carrera, pero eso parece una cantidad excesiva de consultas.Django: Múltiples COUNT de dos modelos de distancia
Esto es lo que "quiero" para ver:
Unassigned: 3
Construction: 2
Farming: 0
Gathering: 1
Aquí es mis modelos. Agrego algo de complejidad al no conectar Carreras directamente a mi modelo de Enanos (se han conectado por sus trabajos).
from django.contrib.auth.models import User
from django.db import models
class Career(models.Model):
name = models.CharField(max_length = 64)
def __unicode__(self):
return self.name
class Job(models.Model):
career = models.ForeignKey(Career)
name = models.CharField(max_length = 64)
career_increment = models.DecimalField(max_digits = 4, decimal_places = 2)
job_increment = models.DecimalField(max_digits = 4, decimal_places = 2)
def __unicode__(self):
return self.name
class Dwarf(models.Model):
job = models.ForeignKey(Job)
user = models.ForeignKey(User)
created = models.DateTimeField(auto_now_add = True)
modified = models.DateTimeField(auto_now = True)
name = models.CharField(max_length = 64)
class Meta:
verbose_name_plural = 'dwarves'
def __unicode__(self):
return self.name
EDIT 1 mi punto de vista se ve algo como:
def fortress(request):
careers = Career.objects.annotate(Count('dwarf_set'))
return render_to_response('ragna_base/fortress.html', {'careers': careers})
y la plantilla:
{% for career in careers %}
<li>{{ career.dwarf_set__count }}</li>
{% endfor %}
El error es:
Cannot resolve keyword 'dwarf_set' into field. Choices are: id, job, name
SOLUCIÓN
vista:
def fortress(request):
careers = Career.objects.all().annotate(dwarfs_in_career = Count('job__dwarf'))
return render_to_response('ragna_base/fortress.html', {'careers': careers})
plantilla:
{% for career in careers reversed %}
<li>{{ career.name }}: {{ career.dwarves_in_career }}</li>
{% endfor %}
solución aún mejor
careers = Career.objects.filter(Q(job__dwarf__user = 1) | Q(job__dwarf__user__isnull = True)) \
.annotate(dwarves_in_career = Count('job__dwarf'))
No se olvide de from django.db.models import Count, Q
Lo que me gusta de la solución anterior es que no solo devuelve carreras que tienen enanos trabajando, sino incluso las carreras que no tienen ninguno, que fue el siguiente problema que encontré. Aquí está mi punto de vista para la integridad:
<ul>
{% for career in careers %}
<li>{{ career.name }}: {{ career.dwarves_in_career }}</li>
{% endfor %}
</ul>
¡No está nada mal! Continúo obteniendo el error: No puedo resolver la palabra clave 'dwarf_set' en el campo. Las opciones son: id, job, name Pero estoy intentando cosas diferentes. – TheLizardKing
Creo que esto funcionaría si mi modelo de Enano estuviera directamente relacionado con mi modelo de Carrera, pero elegí conectar los dos a través de mi modelo de Trabajo para permitir la alteración de las carreras. – TheLizardKing