I have model with two fields:
class Event(models.Model):
date = models.DateField(_(u'Date'))
time = models.TimeField(_(u'Time'))
I need to find all objects where date&time is in 24 hours from now.
I am able to do this when using DateTime field, but I am not sure how to achieve this when fields are separated. Thanks in advance.
For the simple case (not sure if all are simple cases though...), this should do the trick:
import datetime
today = datetime.datetime.now()
tomorrow = today + datetime.timedelta(days=1)
qs_today = queryset.filter(
date=today.date(),
time__gte=today.time(),
)
qs_tomorrow = queryset.filter(
date=tomorrow.date(),
time__lt=tomorrow.time(),
)
qs = qs_today | qs_tomorrow
As you state you can do what you want with a DateTimeField
, but now with the separate fields, I understand your issue is how to combine them.
Looking at the docs for DateField - your date
variable is a datetime.date
instance and similarly for TimeField time
is a datetime.time
. You can convert these into a datetime.datetime
by using combine()
import datetime as dt
datetime = dt.datetime.combine(date,time)
You now have the datetime object as you would have from DateTimeField
. You say in the question you can do the 24 hour from now bit from there, although let me know in comments if you need that made explicit.
Caveat I combine
will fail where one of the fields is None
- you state this can't happen, so I haven't added any error checking or validation of this.
It occurs to me that the problem may not be the combination, but adding the calculated field to the Event
object. You could look at this Q&A, or this. In summary you define the calculated value in a function in your class and then make it a property - either with a decorator or a function call. There's an example in the docs, adapting for your case:
def _get_datetime(self):
'''Returns a combination of date and time as a datetime'''
return dt.datetime.combine(self.date,self.time)
datetime = property(_get_datetime)
This should behave in the same way as you would expect a DateTimeField
to behave.
You can use Q
objects to search for "yesterday after current time or today before current time":
from django.db.models import Q
from .models import Event
from datetime import datetime, timedelta
def get_event_during_last_day():
now = datetime.now()
today = now.date()
yesterday = (now - timedelta(day=1)).date()
time = now.time()
query_yesterday = Q(date=yesterday, time__gt=time)
query_today = Q(date=today, time__lt=time)
return Event.objects.filter(query_yesterday | query_today)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With