Greg Kaleka
Greg Kaleka

Reputation: 1990

Django queryset filter - why is an object meeting all criteria in the filter not included in result set?

My web app is not sending reminders to certain users who should get them. In trying to debug, the following example in a python shell has me pretty confused. Is there anything I'm missing, or doing wrong in the filter?

If there's nothing obviously wrong, how can I debug this issue?

>>> now = timezone.now()
>>> an_hour_ago = now - datetime.timedelta(hours=1)
>>> suz = User.objects.get(email="redacted")
>>> suz.reminded
False
>>> suz.wait_until <= now
True
>>> suz.wait_until >= an_hour_ago
True
>>> suz.is_active
True
>>> remindable = User.objects.filter(is_active=True,
...                                  reminded=False,
...                                  wait_until__gte=an_hour_ago,
...                                  wait_until__lte=now)
>>> suz in remindable
False

Edit: adding in my user model.

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    is_active = models.BooleanField(default=True)
    wait_until = models.DateTimeField(null=True, default=None)
    # etc.

Edit 2: Some additional context:

I have a view in which a user completes a task. After they complete the task, wait_until is set to a random time, based on a range set in a Configuration object. Pertinent code from that view:

config = Configuration.objects.first()
min_minutes = config.min_minutes_between_tasks
max_minutes = config.max_minutes_between_tasks
when = now + datetime.timedelta(minutes=randint(min_minutes,
                                                max_minutes+1))
user.wait_until = when
user.alerted = False
user.save()

Edit 3: I'm not sure what happened, but I'm probably just an idiot.

I restarted my python shell and suz is now returning correctly in remindable as expected. I suspect I had changed one of the attributes above and didn't run suz.save(). That would certainly explain it. ORMs... remember to save() your in-memory objects, kids!

Upvotes: 0

Views: 160

Answers (1)

camelBack
camelBack

Reputation: 778

First of all, add as such as information to the question as possible. It is hard to see the problem when there is not enough background. I still don't know what is this now:

when = now + datetime.timedelta(minutes=randint(min_minutes,
                                                max_minutes+1))

And what is user.alerted? If it doesn't matter, don't show it.

When debugging:

  1. make sure all the things you filter by were used to get the object you are looking for (i.e. what @Alex Hall suggested, add email)
  2. If you can make sure all the different times compared are the same type, and timezone
  3. Try removing filter criteria one by one, see which one may be the issue
  4. Print the QuerySet produced by the filter- what are the objects that were included, vs the ones that were not?
  5. What is the database you are using? It may be storing the time differently when saved

Upvotes: 2

Related Questions