J'ai une fonction qui ressemble à ceci: Je veux seulement compter les postes qui ont leur statut marqué comme "actif". Y a-t-il un moyen simple d'ajouter un filtre avant la fonction de comptage? P> Définitions de modèle: p>
5 Réponses :
Oui. Fais-le. Cela devrait fonctionner comme prévu:
self.thread_set.filter(active_status=1).aggregate(num_posts=Count('post'))['num_posts']
Je suis à peu près sûr que filtrerait le jeu de threads et non les poteaux dans chaque fil.
Whoops, tu as raison. Vous auriez besoin d'obtenir une liste complète des messages d'un fil, puis de filtrer les messages actifs, puis d'agréger ceux-ci. Mais les autres choses à propos d'avoir agrégat () code> dernier reste toujours. Je vais fouiller puis modifier ma réponse.
Je n'ai pas encore de code de code, mais cela ressemble à ce que vous recherchez est-ce: docs.djangoproject.com/fr/dev/topics/db/agregistration/... (jointures et agrégats)
J'ai regardé quelque chose de similaire et j'ai trouvé une excellente solution. J'utilise quelque chose comme ceci:
def post_count(self): return len(Post.objects.filter(someModel = self).filter(active_status = 1))
Pourquoi pas post.Object.filter (Somemodel = Self, Active_Status = 1) .Count ()?
Aussi, j'utilise un agrégat ici car je veux plus que le nombre de post compter sur un thread particulier (représenté par Somemodel dans votre exemple), j'ai besoin du nombre de post pour tous les threads dans une catégorie, c'est pourquoi j'utilise Thread_Set.
Ouais, l'exemple que j'ai donné est assez bâclé. Votre code est définitivement plus propre. Le point que j'essayais de faire est que je suis à peu près sûr que vous devez travailler à travers le modèle de poste et non le modèle de fil.
Si un travail sur le modèle de poste et que j'ai manuellement résumer tous les threads d'une catégorie. Donc, si une catégorie comportait 1000 threads, il faudrait au moins ces nombreuses requêtes pour la DB. De toute évidence, cela ne serait jamais acceptable et je ferais simplement un SQL cru à la place.
Vous voudrez peut-être regarder l'écriture d'un objet de gestionnaire personnalisé: P>
http://docs.djangoproject.com/fr/1.1/ Thèmes / DB / Gestionnaires / P>
Je n'ai pas utilisé agrégat () code>, mais cela peut vous permettre d'écrire un gestionnaire personnalisé pour fournir un
filtré_thread_set code>, puis effectuez
self.active_thread_set. agrégat (...) code>. Sinon, cela vous permettra de faire le SQL personnalisé et d'ajouter un
Num_poststs code> sur les objets code> thread code> (voir le
pollmanager.with_counts () code> exemple .) p>
OK, maintenant que la question inclut les définitions de modèle, je vous soumettais que cela devrait fonctionner, à moins que votre version de Django ne supporte aucune fonctionnalité que j'utilise ici (auquel cas, s'il vous plaît faites le moi savoir!): xxx pré>
django permet aux filtres Ceci devrait filtrer les messages avec Le résultat doit être au plus deux requêtes pour établir une catégorie EDIT: strong> Référence de l'API de requête de Django dit ceci sur dans une liste donnée. p> Exemple: P> __ dans code> de prendre un query pour décider de la clause
in code> doit ressembler à SQL, donc si vous passez
thread__in = thread_set code>, Django filtrera les messages afin que seuls ceux dont le champ code> pointe code> pointe sur l'un des
ID code> S des threads de votre
thread_set code> reste pour le
Agrégation code> Appel à voir. p>
Où thref_id in ... code> à l'intérieur, plutôt qu'avec une requête par fil, ce qui serait effectivement horrible. Si quelque chose d'autre est arrivé, ce serait un bug dans django ... p>
(code> s postcount fort > - Un pour obtenir
thread_set code> et un autre pour compter les messages. L'alternative consiste à faire une jointure de thread / post pour être filtrée en fonction de la catégorie code> 'S code>' S code> champ code> et
post code> s
Statut Le champ, que je ne m'attendrais pas nécessairement à être beaucoup plus rapide.
(je dis 'au plus', parce que je suppose qu'ils pourraient être fusionnés automatiquement ... même si je ne pense pas que cela se produirait avec Django actuel. Je ne peux pas vérifier ATM, désolé.) Strike> p> __ dans code> filtres: p>
inner_q = Blog.objects.filter(name__contains='Cheddar').values('pk').query
entries = Entry.objects.filter(blog__in=inner_q)
C'est la meilleure solution jusqu'à présent. Il peut également être le meilleur que vous puissiez faire avec le django orm. J'espérais juste qu'il y avait un moyen facile d'ajouter un filtre à l'original Self.Thread_SeRead.Accrégation (Num_posts = compter ('Post')) ['Num_post s'].
Eh bien, je me suis finalement arrondi pour regarder les documents sur __ pouce de filtres avec des querySets intérieurs ... on dirait qu'ils devraient jouer assez bien, non? :-) Dommage, je ne peux pas sembler trouver un moyen de brancher facilement un filtre dans votre code, car je peux voir comment cela pourrait être un ajustement plus naturel à une manière particulière de penser à ce que dit le code ... ( Bien que, d'autre part, vous comptez des postes, alors passez à travers la poste me semble correct.) J'espère que cela fonctionne pour votre performance-sage, en tout cas. Tout le meilleur!
serait bien de changer les choses un peu?
Comme illustré ci-dessous, vous pouvez ajouter une propriété post_count à la classe de thread, qui compte des messages actifs dans un fil. P>
Ce post_count pourrait puis être utilisé pour calculer des messages actifs dans une catégorie en ajoutant tous les messages actifs dans tout le thread dans une catégorie. P>
class Category(models.Model): name = models.CharField(max_length=100) slug = models.SlugField(max_length=100, blank=True, primary_key=True) ordering = models.IntegerField(max_length=3, default=0) @property def thread_count(self): return self.thread_set.all().count() @property def post_count(self): # <-- Changed return reduce(lambda x,y: x + y, [x.post_count for x in self.thread_set.all()]) class Thread(models.Model): user = models.ForeignKey(User) category = models.ForeignKey(Category) title = models.CharField(max_length=100) slug = models.SlugField(max_length=100) content = models.TextField() created = models.DateTimeField(auto_now_add=True) latest_activity = models.DateTimeField(auto_now_add=True) @property def post_count(self): # <---- Newly added return self.post_set.filter(status = 'ACTIVE').count() class Post(models.Model): thread = models.ForeignKey(Thread) parent = models.ForeignKey('Post', null=True, blank=True) display_name = models.CharField(max_length=100) email = models.EmailField(db_index=True) ip_address = models.IPAddressField(null=True, blank=True) content = models.TextField() status = models.CharField(choices=STATUS_CHOICES, max_length=25, db_index=True, default='approved') created = models.DateTimeField()
Comment ressemblent vos modèles?