2014-09-07 2 views
0

J'essaie d'utiliser un ListView pour afficher toutes mes villes. Cependant, j'aimerais afficher, pour chaque ville, le nombre de citoyens qui y habitent.Comment compter les objets liés à un élément affiché dans ListView?

Models.py

class Town(models.Model): 
    name = models.CharField() 

class Citizen(models.Model): 
    name = models.CharField() 
    town = models.ForeignKey(Town) 

Views.py

class TownView(ListView): 
    model = Town 
    def get_context_data(self, **kwargs): 
     context = super(TownView, self).get_context_data(**kwargs) 
     context['towns'] = Town.objects.all().prefetch_related('players') 
     return context 

Cela ne fonctionne pas, parce que le prefetch_related ne fonctionnerait si je il y avait un attribut joueur dans la vue de la ville, peut-être par un champ manytomany.

Comment puis-je récupérer, pour chaque ville, le nombre de citoyens dont le lieu d'origine est situé dans cette ville?

En outre, à quoi ressemblerait mon modèle? À l'heure actuelle, il ressemble à ceci:

Modèle

<table> 
{% for town in open_towns %} 
    <tr> 
     <td><a href="/town/join/{{ town.slug }}/">{{ town.name }}</a></td> 
     <td>population : {{ Player.objects.filter(town=town).count() }}</td> 
    </tr> 
{% endfor %} 
</table> 

Mais ceci est évidemment faux aussi.

Répondre

2

Ressemble annotate fonctionnalité ce dont vous avez besoin:

Town.objects.annotate(population=Count('players')) 

Et dans le modèle:

<table> 
{% for town in open_towns %} 
    <tr> 
     <td><a href="/town/join/{{ town.slug }}/">{{ town.name }}</a></td> 
     <td>population : {{ town.population }}</td> 
    </tr> 
{% endfor %} 
</table> 
3

Qu'est-ce que vous avez réellement besoin ici est l'annotation. Vous pouvez le faire sans outrepasser aucune méthode.

from django.db.models import Count 

class TownView(ListView): 
    queryset = Town.objects.all().annotate(citizen_count=Count('citizen')) 

Maintenant, chaque élément du object_list possède une propriété citizen_count.

Questions connexes