J'essaie de déterminer s'il y a moyen de faire une agrégation quelque peu complexe dans Django en utilisant son ORM, ou si je dois utiliser extra() pour coller quelque chose de brut SQLAgrégation entre les colonnes de Django
Voici mes modèles d'objet (dépouillées pour montrer juste l'essentiel):
class Submission(Models.model)
favorite_of = models.ManyToManyField(User, related_name="favorite_submissions")
class Response(Models.model)
submission = models.ForeignKey(Submission)
voted_up_by = models.ManyToManyField(User, related_name="voted_up_responses")
Ce que je veux faire est la somme de toutes les voix pour une communication donnée: c'est, tous les votes pour l'une des ses réponses, puis en incluant également le nombre de personnes qui ont marqué la soumission en tant que favori.
J'ai la première partie de travail en utilisant le code suivant; cela renvoie le total des voix toutes les réponses de chaque soumission:
submission_list = Response.objects\
.values('submission')\
.annotate(votes=Count('voted_up_by'))\
.filter(votes__gt=0)\
.order_by('-votes')[:TOP_NUM]
(. Donc, après avoir obtenu le total des votes, je trie par ordre décroissant et retourner les meilleures soumissions de TOP_NUM, pour obtenir un « best of » annonce)
Cette partie fonctionne. Est-il possible de suggérer d'inclure le nombre de personnes qui ont favorisé chaque soumission dans ses votes? (Je préfèrerais éviter extra() pour la portabilité, mais je pense que cela peut être nécessaire, et je suis prêt à l'utiliser.)
EDIT: J'ai réalisé après avoir lu les suggestions ci-dessous que je devrais avoir été plus clair dans ma description du problème. La solution idéale serait celle qui m'a permis de trier par le nombre total de votes (la somme de voted_up_by
et favorited
), puis de choisir seulement le nombre le plus élevé, tous dans la base de données. Si ce n'est pas possible, je suis prêt à charger quelques-uns des champs de chaque réponse et à faire le traitement en Python; mais comme je traiterai plus de 100 000 enregistrements, ce serait bien d'éviter cette surcharge. (En outre, à Adam et Dmitry: Je suis désolé pour le retard dans la réponse!)