J'ai un modèle similaire à ce qui suit:
class Review(models.Model):
venue = models.ForeignKey(Venue, db_index=True)
review = models.TextField()
datetime_created = models.DateTimeField(default=datetime.now)
J'aimerais interroger la base de données pour obtenir le nombre total de commentaires pour un lieu groupé de jour. La requête MySQL serait:
SELECT DATE(datetime_created), count(id)
FROM REVIEW
WHERE venue_id = 2
GROUP BY DATE(datetime_created);
Quel est le meilleur moyen d'accomplir cela à Django? Je pourrais juste utiliser
Review.objects.filter(venue__pk=2)
et analyser les résultats dans la vue, mais cela ne me semble pas juste.
Cela devrait fonctionner (en utilisant la même fonction spécifique MySQL que vous avez utilisée):
Review.objects.filter(venue__pk=2)
.extra({'date_created' : "date(datetime_created)"})
.values('date_created')
.annotate(created_count=Count('id'))
Juste pour l'exhaustivité, étant donné plus () vise une dépréciation, on pourrait utiliser cette approche:
from Django.db.models.expressions import DateTime
Review.objects.all().\
annotate(month=DateTime("timestamp", "month", pytz.timezone("Etc/UTC"))).\
values("month").\
annotate(created_count=Count('id')).\
order_by("-month")
Cela a fonctionné pour moi dans Django 1.8, dans les bases de données SQLITE et MYSQL.
Maintenant que Extra()
est en cours de dépréciation une réponse plus appropriée utiliserait Trunc telle que cette réponse acceptée
Maintenant, la question de l'OP serait répondu comme suit
from Django.db.models.functions import TruncDay
Review.objects.all()
.annotate(date=TruncDay('datetime_created')
.values("date")
.annotate(created_count=Count('id'))
.order_by("-date")
Si vous stockiez un champ de date, vous pouvez utiliser ceci:
from Django.db.models import Count
Review.objects.filter(venue__pk = 2)
.values('date').annotate(event_count = Count('id'))
Parce que vous stockez DateTime, c'est un peu plus compliqué, mais cela devrait offrir un bon point de départ. Découvrez les documents d'agrégation ici .