I could be a bit more pythonic:
>>> from django.db.models.query import QOr
>>> ql = [Q(birthdate__day=(startdate + timedelta(days=x)).day) & 
>>> Q(birthdate__month=(startdate + timedelta(days=x)).month) for x in range(7)]
>>> Person.objects.filter(QOr(*ql))

 -rob

On Jun 19, 2:51 pm, Tim Chase <[EMAIL PROTECTED]> wrote:
> > I want to compare dates in my db while ignoring the year field. Lets
> > say I have a birthday field and want to find upcoming birthdays in the
> > next one week. How can I achieve this? If I try-
>
> > last_date = datetime.now().date() + timedelta(days=7)
> > users = User.objects.filter(birthday__day__lte = last_date.day)
>
> This is a bit tricky, especially because of boundary conditions
> like ends-of-months and end-of-years.  Note that if it's
> currently December 28th, last_date.day isn't quite what you want
> to be comparing to.
>
> This can be done on the DB-server-side if you do server-specific
> code; it can be done on the Django side in homogenous Python code
> if you're willing to slurp over all your germane birthdays and
> filter them locally; or, with such a small range of days (fixed
> at 7), you could do something hackish like:
>
>   now = datetime.now().date()
>   dates = [now + timedelta(days=x) for x in xrange(8)]
>   from operator import or_
>   params = reduce(or_, [
>     Q(birthday__day=date.day, birthday__month=date.month)
>     for date in dates
>     ])
>   users = User.objects.filter(*params)
>
> This gets a little unweildy if you have more than a couple days
> to consider (I don't think I'd do this for more than about 10
> days).  It basically builds something of the form
>
>   ...filter(Q(birthday__day=now.day, birthday__month=now.month) |
>     Q(birthday__day=now.day + timedelta(days=1),
>       birthday__month=now.month + timedelta(days=1)) |
>     Q(birthday__day=now.day + timedelta(days=2),
>       birthday__month=now.month + timedelta(days=2)) |
>     Q(birthday__day=now.day + timedelta(days=3),
>       birthday__month=now.month + timedelta(days=3)) |
>     ...
>
> for each of your days.  (thus a cap on 7 days is good...smaller
> is better)
>
> However, the alternative on the server side would be to write
> DB-specific code doing some crazy date math using functions like
> MySQL's DateAdd function.  The high-level picture would involve
> normalizing the field's date to the year that falls within the
> given range and then comparing it with BETWEEN to ensure it falls
> between the two calculated dates.  Something like this 100%
> untested code:
>
>    now = datetime.now().date()
>    end = now + timedelta(days=7)
>    users = User.objects.extra(where="""
>      adddate(birthday, interval
>        (Extract(year from %s) - Extract(year from birthday))
>        years)
>        BETWEEN %s AND %s
>      """,
>      params = [now, now, end])
>
> You might have to tweak it to add 1 to the year if there's some
> odd boundary straddling.
>
> -tim


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to