2010-08-22 33 views
15

Tôi có một mô hình rất cơ bản:Django chú thích nhóm theo tháng

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) 

tôi có thể tạo ra một danh sách tất cả các mục được nhóm theo ngày sử dụng:

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

này sẽ tự nhiên mặt hàng nhóm theo ngày . Nhưng những gì tôi thực sự muốn làm là nhóm theo tháng. Có anyway tôi có thể làm điều này bằng cách sử dụng chú thích()?

Rất cám ơn,

G

+0

Không trả lời, nhưng bạn có thể xem qua vé này: http://code.djangoproject.com/ticket/10302 –

+0

'Đếm' là gì? –

Trả lời

15

Nếu bạn đang ở trên PostgreSQL, sau đây có thể làm việc:

from django.db.models import Count 

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

Tôi không chắc chắn như thế nào di extract là trên cơ sở dữ liệu khác.

+0

Cảm ơn! Điều này dường như cũng làm việc cho mySQL. Ngoại trừ nhóm này tất cả các tháng qua bất kỳ năm nào. Tôi đang cố gắng để có được nhóm tháng cho mỗi năm. Nhưng đây là một khởi đầu tuyệt vời vì vậy tôi sẽ tinh chỉnh. Cảm ơn một lần nữa. – givp

+0

bạn có thể tát một bộ lọc trong đó giới hạn ngày cho các phạm vi nhất định. '.filter (pub_date__gte = datetime.datetime (điền vào ngày ở đây))' – boatcoder

+4

bằng cách sử dụng 'connection.ops.date_trunc_sql ('month', 'date')' thay vì SQL giải mã hardcoded sẽ làm cho câu lệnh tương thích với các backend khác – 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

rằng bạn cũng phải nhập 'từ nhập khẩu django.db.models Count' –

3

Để thêm, thay thế cho việc sử dụng extra(): kể từ Django 1.8, bạn cũng có thể sử dụng biểu thức có điều kiện.

>>> 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

Với phiên bản Django mới nhất, tôi đoán đây là giải pháp được đề xuất –

2

Tôi đã đọc rằng .extra() sẽ không được dùng nữa trong tương lai. Thay vào đó, họ đề xuất sử dụng các đối tượng Func. Và có một cách để trích xuất một tháng mà không sử dụng câu lệnh Case đau đớn.

from django.db.models.functions import ExtractMonth 
Link.objects.all().annotate(pub_date_month=ExtractMonth('pub_date')) 
Các vấn đề liên quan