Melissa Stewart
Melissa Stewart

Reputation: 3625

Django query chaining multiple filters

This is my schedule object:

class Schedule(Base):
    tournament = models.ForeignKey(Tournament, on_delete=models.CASCADE, null=True)
    first_team = models.ForeignKey(Team, related_name="first_team", on_delete=models.CASCADE, null=True)
    second_team = models.ForeignKey(Team, related_name="second_team", on_delete=models.CASCADE, null=True)
    first_score = models.IntegerField(default=0, null=True)
    second_score = models.IntegerField(default=0, null=True)
    sport = models.ForeignKey(Sport, on_delete=models.CASCADE, null=True)
    date = models.DateTimeField()

I want to fetch the schedules for a specific sport, for the past 30 days for tournaments which have anything other than a 0.0 bias.

This is my query:

schedules = Schedule.objects.filter(sport=sport).filter(date__gte=date.today()).filter(
                        date__lte=(date.today() + timedelta(days=30))).order_by("date").exclude(tournament__bias=0.0)

This doesn't work. What can I try next?

Upvotes: 1

Views: 93

Answers (3)

Shakil
Shakil

Reputation: 4630

Your chaining filter looks like almost correct but i guess you messing with past 30 days section filtering.

schedules = Schedule.objects.filter(sport=sport).filter(date__lt=date.today()).filter(
                        date__gte=(date.today() - timedelta(days=30))).order_by("date").exclude(tournament__bias=0.0)

Upvotes: 1

Ralf
Ralf

Reputation: 16515

Just to be sure, you should be using tz.now() instead of date.today(), because you probably have USE_TZ = True (the default value). See the django docs.

Also, you have to invert your date filters, because you are searching for 30 days into the future, not the past.

import datetime
from django.utils import timezone as tz

today = tz.localtime(tz.now()).date()
start_date = today - datetime.timedelta(days=30)
end_date = today

schedules = Schedule.objects.exclude(tournament__bias=0.0) \
    .filter(sport=sport, date__gte=start_date, date__lte=end_date) \
    .order_by("date")

Upvotes: 1

dirkgroten
dirkgroten

Reputation: 20702

Your code is correct way of filtering (although you could merge the two filter() methods by comma-separating the lookups).

The problem might be that you're now filtering for:

today() <= date <= today() + 30 days 

So if you don't have any instances with a date in the future 30 days (or today), you'll get an empty set.

Upvotes: 3

Related Questions