2010-07-01 8 views
3

J'ai un modèle Django qui définit un intervalle de temps. Chaque TimeSlot peut contenir un certain nombre d'utilisateurs (TimeSlot.spots). Chaque TimeSlot a également un certain nombre d'utilisateurs déjà détenus (un champ plusieurs à plusieurs, TimeSlot.participantsOpérations mathématiques sur les annotations Django

Lorsque je passe au modèle qui affiche les TimeSlots disponibles à l'utilisateur, j'annote avec TimeSlot.objects.annotate(Count('participants')), ce qui donne le numéro des utilisateurs actuellement détenu par l'intervalle de temps que participants__count.

Cependant, ce que je veux vraiment est le nombre de places restantes, la capacité (TimeSlot.spots) moins le nombre actuellement détenu (participants__count). Comment puis-je annoter un autre domaine avec cette nouvelle nombre, donc je peux le passer au modèle?

+0

double possible de [deux colonnes annotés Soustraction] (http://stackoverflow.com/questions/17374467/ soustrayant-deux colonnes annotées) – Louis

Répondre

1

Non possible avec seulement une annotation. Je créer une méthode sur le modèle qui fait l'annotation, puis soustraire cela de votre valeur TimeSlot.spots. Cela va utiliser plus de requêtes de base de données, mais c'est votre seule option. Ou je suppose que vous pourriez descendre au SQL brut ...

+0

Merci, j'étais inquiet que cela pourrait être le cas. Je pense que ce que je finirai par faire est de configurer le ManyToManyManager sur le 'TimeSlot.participants' de sorte que chaque fois qu'il ajoute une personne, il décrémente' TimeSlot.spots ', ce qui est un peu moins élégant mais nettement moins cher à long terme . – stillinbeta

2

Ce n'est toujours pas possible avec l'annotation (bien qu'il soit prévu de l'implémenter dans Django). Mais vous pouvez le faire avec une requête .extra(). Voir mon answer à une autre question pour plus de détails.

Upd .:

Essentiellement, vous avez besoin somethig comme cette requête:

items = MyModel.objects.extra(
    select = {'variance': 'Model.someField - SUM(relatedModel__someField)'}, 
) 
Questions connexes