2011-05-09 109 views
1

我有類似的模型,以這樣的:Django的:總的生日每一天接下來的30天內

class Person(models.Model): 
    name = models.CharField(max_length=40) 
    birthday = DateTimeField() # their next birthday 

我想獲得總生日每天的列表在未來30天。因此,例如,該列表是這樣的:

[[9, 0], [10, 3], [11, 1], [12, 1], [13, 5], ... #30 entries in list 

列表中的每個列表項的日期數字,然後在這一天過生日的數量。例如5月9日有0個生日。

最新通報

我的數據庫是sqlite3的 - 會動在未來的Pos​​tgres。

+0

掛起 - 生日場是他們在*本年*的生日,或他們的實際出生日期? – 2011-05-09 12:39:15

+0

是的,這將是他們今年的生日。 – ErnieP 2011-05-09 12:44:31

回答

2

我會得到天的列表和生日指望這樣:

from datetime import date, timedelta  
today = date.today() 
thirty_days = today + timedelta(days=30) 

# get everyone with a birthday 
people = Person.objects.filter(birthday__range=[today, thirty_days]) 

birthday_counts = [] 
for date in [today + timedelta(x) for x in range(30)]: 
    # use filter to get only birthdays on given date's day, use len to get total 
    birthdays = [date.day, len(filter(lambda x: x.birthday.day == date.day, people))] 
    birthday_counts.append(birthdays) 
+0

這似乎是個訣竅,非常感謝你!!! – ErnieP 2011-05-09 14:48:13

+0

謝謝,儘管使用'annotate'方法將count和日期結合起來更好。你應該使用[丹尼爾羅斯曼的答案](http://stackoverflow.com/questions/5936966/django-total-birthdays-each-day-for-the-next-30-days/5937638#5937638),而不是 – zeekay 2011-05-09 15:36:57

+0

但作爲丹尼爾說,他的方法不適用於DateTime,這是我的。 – ErnieP 2011-05-10 05:52:57

0

事情是這樣的 -

from datetime import date, timedelta 

class Person(models.Model): 
    name = models.CharField(max_length=40) 
    birthday = models.DateField() 

    @staticmethod 
    def upcoming_birthdays(days=30): 
     today = date.today() 
     where = 'DATE_ADD(birthday, INTERVAL (YEAR(NOW()) - YEAR(birthday)) YEAR) BETWEEN DATE(NOW()) AND DATE_ADD(NOW(), INTERVAL %S DAY)' 
     birthdays = Person.objects.extra(where=where, params=[days]).values_list('birthday', flat=True) 
     data = [] 
     for offset in range(0, days): 
      i = 0 
      d = today + timedelta(days=offset) 
      for b in birthdays: 
       if b.day == d.day and b.month == d.month: 
        i += 1 
      data.append((d.day, i)) 
     return data 

print Person.upcoming_birthdays() 
+0

謝謝!這將與sqlite3(我目前的開發數據庫)工作? – ErnieP 2011-05-09 13:02:00

+0

我想你不需要那個自定義SQL。此外,引用多個對象的函數在Manager上的效果要好於Model – Eduardo 2011-05-09 13:08:00

4
from django.db.models import Count 
import datetime 
today = datetime.date.today() 
thirty_days = today + datetime.timedelta(days=30) 
birthdays = dict(Person.objects.filter(
        birthday__range=[today, thirty_days] 
       ).values_list('birthday').annotate(Count('birthday'))) 


for day in range(30): 
    date = today + datetime.timedelta(day) 
    print "[%s, %s]" % (date, birthdays.get(date, 0)) 
+0

。使用[range](http://docs.djangoproject.com/en/dev/ref/models/querysets/#range)字段查找絕對是要走的路。 – zeekay 2011-05-09 13:48:13

+0

但你不想避免'聚合'?最後一部分不起作用。 – zeekay 2011-05-09 13:56:05

+0

爲什麼?爲什麼它不工作? – 2011-05-09 14:04:15

0

(的人在接下來的X生日查詢集天) 找到了很酷的解決方案! 對我而言它有效!

from datetime import datetime, timedelta 
import operator 

from django.db.models import Q 

def birthdays_within(days): 

    now = datetime.now() 
    then = now + timedelta(days) 

    # Build the list of month/day tuples. 
    monthdays = [(now.month, now.day)] 
    while now <= then: 
     monthdays.append((now.month, now.day)) 
     now += timedelta(days=1) 

    # Tranform each into queryset keyword args. 
    monthdays = (dict(zip(("birthday__month", "birthday__day"), t)) 
       for t in monthdays) 


    # Compose the djano.db.models.Q objects together for a single query. 
    query = reduce(operator.or_, (Q(**d) for d in monthdays)) 

    # Run the query. 
    return Person.objects.filter(query) 

但它得到一個在日期範圍內有生日的人的列表。你應該改變一下。