'Merge Date Time in Django ORM
I was trying to combine date and time. For that i was using datetime.combine
. But it is giving AttributeError module 'datetime' has no attribute 'combine'
TimesheetEntry.objects.filter(
timesheet_users = user_id
).order_by(
'-id'
).annotate(
timesheet_clock_in=datetime.combine('timesheet_clock_in_date', 'timesheet_clock_in_time')
).annotate(
timesheet_clock_out=datetime.combine('timesheet_clock_out_date', 'timesheet_clock_out_time')
).values_list(
'timesheet_clock_in',
'timesheet_clock_out',
'timesheet_jobs',
'timesheet_note',
'timesheet_clock_in_by'
)
I know the error is in annotate
but i don't how to solve it. Query works without annotate
Solution 1:[1]
In addition to this answer, use F()
expressionas
from django.db.models import F
from datetime import datetime
TimesheetEntry.objects.filter(
timesheet_users=user_id
).order_by(
'-id'
).annotate(
timesheet_clock_in=datetime.combine(F('timesheet_clock_in_date'), F('timesheet_clock_in_time'))
).annotate(
timesheet_clock_out=datetime.combine(F('timesheet_clock_out_date'), F('timesheet_clock_out_time'))
).values_list(
'timesheet_clock_in',
'timesheet_clock_out',
'timesheet_jobs',
'timesheet_note',
'timesheet_clock_in_by'
)
Solution 2:[2]
Did you import datetime
correctly?
import datetime
# The datetime module
or
from datetime import datetime
# The datetime class in the datetime module
In the first case you should call datetime.datetime.combine
(with 2x datetime
). In the second case you can call datetime.combine
directly.
Solution 3:[3]
date.combine()
does not work because it raises argument 1 must be datetime.date, not F
Here is how we approached this issue:
from django.db.models import Value
from django.db.models.functions import Cast, Concat
TimesheetEntry.objects.filter(
timesheet_users=user_id
).order_by(
'-id'
).annotate(
timesheet_clock_in=Cast(
Concat('timesheet_clock_in_date', Value(" "), 'timesheet_clock_in_time', output_field=DateTimeField()),
output_field=DateTimeField()
)
timesheet_clock_out=Cast(
Concat('timesheet_clock_out_date', Value(" "), 'timesheet_clock_out_time', output_field=DateTimeField()),
output_field=DateTimeField()
)
).values_list(
'timesheet_clock_in',
'timesheet_clock_out',
'timesheet_jobs',
'timesheet_note',
'timesheet_clock_in_by'
)
Solution 4:[4]
You can do it in the database instead of in the ORM:
TimesheetEntry.objects.filter(
timesheet_users = user_id
).order_by(
'-id'
).annotate(
timesheet_clock_in=ExpressionWrapper(F("timesheet_clock_in_date") + F("timesheet_clock_in_time"), output_field=DateTimeField())
).annotate(
timesheet_clock_out=ExpressionWrapper(F("timesheet_clock_out_date") + F("timesheet_clock_out_time"), output_field=DateTimeField())
).values_list(
'timesheet_clock_in',
'timesheet_clock_out',
'timesheet_jobs',
'timesheet_note',
'timesheet_clock_in_by'
)
+
is the Postgres operator for date + time ? timestamp so make sure you're using the correct operator for your database.
Also as a note to anyone doing this: Be careful of timezone issues when combining date and time into timestamps.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | Arash77 |
Solution 4 | SebastianR |