2010-09-28 4 views
1

J'ai une pile de modèles quelque chose comme ça (je tape dans ce raccourci relatif):comptage rapide avec les modèles liés Django

class User: 
    pass 


class ItemList: 
    pass 


# A User can have more than one ItemList 
# An ItemList can have more than one User 
# Classic M2M 

class ItemListOwnership: 
    user = fk(User) 
    itemlist = fk(ItemList) 


# An ItemList has multiple Items 

class Item: 
    itemlist = fk(ItemList) 

Ce que je veux faire est d'afficher un nombre simple combien d'éléments un utilisateur donné (ou un ensemble d'utilisateurs existant) a sur leurs différentes listes. Je dois compter sur la division M2M.

Voilà où je suis coincé. Je suis content avec une méthode SQL pure si c'est la seule chose qui fonctionne mais je ne veux vraiment pas entrer dans une situation où j'émets n + 1 requêtes par utilisateur (où n est le nombre de listes l'utilisateur a) juste pour un compte ...

Editer: Je n'utilise pas une relation "réelle" models.ManyToMany(..) parce que je définis des choses supplémentaires dans ItemListOwnership qui décrivent la relation un peu mieux. Si c'est un tueur, je peux probablement déplacer ces métadonnées ailleurs et se débarrasser de ItemListOwnership et coller un m2m dans ItemList

Répondre

3

Tout d'abord, la définition des champs supplémentaires dans une table de liaison est ce que la fonctionnalité through de ManyToManyField est pour. Donc, gardez votre table ItemListOwnership avec ses FK, mais ajoutez un userlist=ManyToMany('User', through='ItemListOwnership') à UserList.

Une fois que vous avez fait cela, vous pouvez facilement compter le nombre d'éléments pour chaque utilisateur en utilisant annoter:

from django.db.models import Count 
User.objects.all().annotate(item_count=Count('userlist__item')) 

Maintenant, chaque utilisateur a un attribut item_count qui est le nombre d'articles qu'ils ont.