2010-08-22 8 views
15

ich ein sehr einfaches Modell haben:Django Gruppierungen von Monat mit Anmerkungen versehen

class Link(models.Model): 
    title = models.CharField(max_length=250, null=False) 
    user = models.ForeignKey(User) 
    url = models.CharField(max_length=250, blank=True, null=True) 
    link_count = models.IntegerField(default=0) 
    pub_date = models.DateField(auto_now_add=True) 
    updated = models.DateTimeField(auto_now=True) 

ich nach dem Datum eine Liste aller Einträge erstellen können mit gruppiert:

Link.objects.values('pub_date').order_by('-pub_date').annotate(dcount=Count('pub_date')) 

Dies wird von Tag natürlich Artikel Gruppe . Aber was ich wirklich machen möchte, ist Gruppe für Monat. Gibt es das überhaupt, kann ich das mit annotate() tun?

Vielen Dank,

G

+0

keine Antwort, aber Sie könnten eine Blicke auf diesem Ticket nehmen: http://code.djangoproject.com/ticket/10302 –

+0

was 'Count'? –

Antwort

15

Wenn Sie auf PostgreSQL sind, könnten folgende Arbeiten:

from django.db.models import Count 

Link.objects.extra(select={'month': 'extract(month from pub_date)'}).values('month').annotate(dcount=Count('pub_date')) 

Ich bin nicht sicher, wie tragbare extract über andere Datenbanken ist.

+0

Danke! Dies scheint auch für mySQL zu funktionieren. Außer diesem gruppiert alle Monate über jedes Jahr. Ich versuche Monate für jedes Jahr zu gruppieren. Aber das ist ein guter Anfang, also werde ich zwicken. Danke noch einmal. – givp

+0

Sie können einen Filter dort drängen, der die Daten zu bestimmten Bereichen begrenzt. '.filter (pub_date__gte = datetime.datetime (Datum hier eingeben))' – boatcoder

+4

mit 'connection.ops.date_trunc_sql ('Monat', 'Datum')' anstelle von hardcoded Extract SQL würde die Anweisung kompatibel mit anderen Back-Ends gemacht – jujule

13
from django.db import connections 
from django.db.models import Count 

Link.objects.extra(select={'month': connections[Link.objects.db].ops.date_trunc_sql('month', 'pub_date')}).values('month').annotate(dcount=Count('pub_date')) 
+1

Hinweis dass du auch importieren musst 'from django.db.models import Count' –

3

hinzuzufügen, als Alternative für die Verwendung von extra(): da Django 1.8, können Sie auch bedingte Ausdrücke verwenden.

>>> year_overview = Link.objects.filter(pub_date__year=year).aggregate(
    jan=Sum(
     Case(When(created__month=0, then=1), 
      output_field=IntegerField()) 
    ), 
    feb=Sum(
     Case(When(created__month=1, then=1), 
      output_field=IntegerField()) 
    ), 
    mar=Sum(
     Case(When(created__month=2, then=1), 
      output_field=IntegerField()) 
    ), 
    apr=Sum(
     Case(When(created__month=3, then=1), 
      output_field=IntegerField()) 
    ), 
    may=Sum(
     Case(When(created__month=4, then=1), 
      output_field=IntegerField()) 
    ), 
    jun=Sum(
     Case(When(created__month=5, then=1), 
      output_field=IntegerField()) 
    ), 
    jul=Sum(
     Case(When(created__month=6, then=1), 
      output_field=IntegerField()) 
    ), 
    aug=Sum(
     Case(When(created__month=7, then=1), 
      output_field=IntegerField()) 
    ), 
    sep=Sum(
     Case(When(created__month=8, then=1), 
      output_field=IntegerField()) 
    ), 
    oct=Sum(
     Case(When(created__month=9, then=1), 
      output_field=IntegerField()) 
    ), 
    nov=Sum(
     Case(When(created__month=10, then=1), 
      output_field=IntegerField()) 
    ), 
    dec=Sum(
     Case(When(created__month=11, then=1), 
      output_field=IntegerField()) 
    ), 
) 

>>> year_overview 
{'mar': None, 'feb': None, 'aug': None, 'sep': 95, 'apr': 1, 'jun': None, 'jul': None, 'jan': None, 'may': None, 'nov': 87, 'dec': 94, 'oct': 100} 
+2

Mit der neuesten Django-Version denke ich, das ist die empfohlene Lösung –

2

Ich habe gelesen, dass .extra() in der Zukunft veraltet sein wird. Sie schlagen vor, stattdessen Func Objekte zu verwenden. Und es gibt einen für das Extrahieren eines Monats ohne eine schmerzhafte Case Aussage zu verwenden.

from django.db.models.functions import ExtractMonth 
Link.objects.all().annotate(pub_date_month=ExtractMonth('pub_date')) 
Verwandte Themen