2011-05-09 114 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) 

但它得到一个在日期范围内有生日的人的列表。你应该改变一下。