python - Contar el número de registros por fecha en Django
django-models django-queryset (5)
Ahora que Extra()
se está depreciando, una respuesta más apropiada usaría Trunc , como esta respuesta aceptada.
Ahora la pregunta del OP sería respondida de la siguiente manera
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")
Tengo un modelo similar al siguiente:
class Review(models.Model):
venue = models.ForeignKey(Venue, db_index=True)
review = models.TextField()
datetime_created = models.DateTimeField(default=datetime.now)
Me gustaría consultar la base de datos para obtener el número total de reseñas para un lugar agrupado por día. La consulta de MySQL sería:
SELECT DATE(datetime_created), count(id)
FROM REVIEW
WHERE venue_id = 2
GROUP BY DATE(datetime_created);
¿Cuál es la mejor manera de lograr esto en Django? Podría simplemente usar
Review.objects.filter(venue__pk=2)
y analizar los resultados en la vista, pero eso no me parece correcto.
Esto debería funcionar (usando la misma función específica de MySQL que usaste):
Review.objects.filter(venue__pk=2)
.extra({''date_created'' : "date(datetime_created)"})
.values(''date_created'')
.annotate(created_count=Count(''id''))
Si estuviera almacenando un campo de fecha, podría usar esto:
from django.db.models import Count
Review.objects.filter(venue__pk = 2)
.values(''date'').annotate(event_count = Count(''id''))
Debido a que está almacenando fecha y hora, es un poco más complicado, pero esto debería ofrecer un buen punto de partida. Consulte los documentos de agregación here .
Solo para completar, dado que extra () apunta a la desaprobación, uno podría usar este enfoque:
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")
Me funcionó en django 1.8, tanto en las bases de datos sqlite como en MySql.
También puedes definir una función personalizada:
from django.db.models.expressions import Func
# create custom sql function
class ExtractDateFunction(Func):
function = "DATE" # thats the name of function, the way it mapped to sql
# pass this function to annotate
Review.objects.filter(venue__pk=2)
.annotate(date_created=ExtractDateFunction("datetime_created"))
.values(''date_created'')
.annotate(created_count=Count(''id''))
Solo asegúrate de que tu motor de DB soporte la función DATE