0

I have been searching a lot, and it's strange to me that nobody here had a similar problem. Well, in general, I need to query "available" tests which could be submitted. Let me explain this in details:

I have my model (and not a permission to change it):

class ScheduledTest(BaseModel):
    start = models.DateTimeField()
    duration = models.DecimalField(verbose_name="Duration (in hours)", max_digits=5, decimal_places=2)

    test_setup = models.ForeignKey(TestSetup, related_name="scheduled_tests")
    creator = models.ForeignKey(AppUser, related_name="scheduled_tests")

    def __str__(self):
        return self.test_setup.title +  " | " + self.test_setup.subject.title + \
               " | {}".format(self.start.date()) + " | Duration: {} h".format(self.duration)

Now I want to query for ScheduledTests that have their start datetime between timezone.now() and timezone.now() + test.duration plus tests that have their start datetime bigger than timezone.now().

So this is my try:

self.queryset = ScheduledTest.objects.all()

available_tests = \
    self.queryset.filter(start__gte=timezone.now())\
        .union(self.queryset.filter(start__range=(timezone.now(), timezone.now() + timezone.timedelta(hours=F('duration'))))
)

But... of course I get an exception because F('duration') cannot be calculated before the query is executed. Precisely, I get an error that hours expects float as an argument and not the F()

Please help, what can I do?

My idea is to somehow make a statement that will achieve conversion from float to date directly in the DB query, but I don't know how to do that since I am a beginner with Django. I am using Django v1.11.

adkl
  • 634
  • 7
  • 17
  • Assuming `test.duration` is non-negative, as written, your two conditions overlap (i.e. `start` > `timezone.now()` for every `timezone.now()` < `start` < `timezone.now() + test.duration`). You could simplify the query to `self.queryset.filter(start__gte=timezone.now())` without impacting your result. – whp Dec 31 '17 at 22:47
  • Ou, my bad, it's a typo, but still I need both of the tests. Ones with `now() < start`, and ones with `start < now() < start+duration` – adkl Jan 01 '18 at 20:10

0 Answers0