J'ai une table contenant une série d'entrées qui concernent des périodes de temps (spécifiquement, le temps travaillé pour un client): J'essaie de regrouper tout le temps travaillant pour une donnée. Client, de mon application Django: p> Cela semble inélégant, mais il fonctionne em>. Ou au moins alors je pensais: il s'avère que cela fonctionne bien sur une base de données PostgreSQL, mais lorsque je passe à Sqlite, tout meurt. P> Un peu de creusement suggère que la raison en est que Code> DateTime CODE> S n'est pas des données de première classe dans SQLite. La requête SQLITE crue suivante fera mon travail: P> Je devrais mentionner pour le contexte que l'ensemble de données est à plusieurs milliers d'entrées; Ce qui suit n'est pas vraiment pratique: p> sum([task_time.end_date - task_time.start_date for task_time in models.TaskTime.objects.filter(...)])
3 Réponses :
Django ne prend actuellement que prend en charge les agrégats pour min, max, avg et compter, il est donc le seul moyen de réaliser ce que vous voulez. Lorsque vous utilisez RAW SQL, la base de données-Indépendance est sortie de la fenêtre, alors malheureusement, vous n'avez pas de chance. Vous devrez simplement détecter la base de données et modifier correctement le SQL. P>
N'est plus une réponse valide
Je pense depuis Django 1.8 Nous pouvons faire mieux:
Je voudrais juste dessiner la pièce avec annotation, la partie supplémentaire avec agrégation doit être simple: p> [Plus sur la fonction d'âge des postgres ici: http: //www.postgresql. org / docs / 8.4 / statique / fonctions-DateTime.html ] p> Chaque instance de SOMEMODEL sera anotée avec Durée Code> Différence temporelle de champ, qui dans Python Soyez un
DateTime.Timedelta () CODE> Objet [plus sur DateTime TimeDelta Ici: https://docs.python.org/2/library/dateTime.html#timedelta-Objects ] p> p>
Très impressionnant. Merci.
presque la même solution que @andri proposé. Dans le résultat final, vous obtiendrez les mêmes données.
ExpressWrapper - Nouveau à Django 1.8. A > from datetime import timedelta
from django.db.models import ExpressionWrapper, F, fields
from app.models import MyModel
duration = ExpressionWrapper(F('closed_at') - F('opened_at'), output_field=fields.DurationField())
objects = MyModel.objects.closed().annotate(duration=duration).filter(duration__gt=timedelta(seconds=2))
for obj in objects:
print obj.id, obj.duration, obj.duration.seconds
# sample output
# 807 0:00:57.114017 57
# 800 0:01:23.879478 83
# 804 3:40:06.797188 13206
# 801 0:02:06.786300 126
Je pense que votre réponse n'est pas exacte, car dans le contexte du calcul du temps Delta, nous n'avons pas à voir avec différents types, et ExpressWrapper est nécessaire lors de l'utilisation de l'arithmétique sur les expressions F () avec différents types CODE> docs.djangoproject.com/fr/1.8/ref/ Modèles / expressions / ...