django queryset with __date returns Nones - django

I have a django queryset where I want to group by created_at date value (created_at is a datetime field).
(Activity.objects
.values('created_at__date')
.annotate(count=Count('id'))
.values('created_at__date', 'count')
)
I am following the accepted answer here which makes sense. However, the query returns None for all created_at__date values. When I change it to created_at it shows the actual value.
The generated SQL query:
SELECT
django_datetime_cast_date("activity"."created_at", 'UTC', 'UTC'),
COUNT("activity"."id") AS "count"
FROM
"activity"
GROUP BY
django_datetime_cast_date("activity"."created_at", 'UTC', 'UTC')
I am working with local sqlite3 database, some sample records from DB (the other columns in the table are removed):
2,2021-07-30T11:44:09.984439+00:00
3,2021-07-30T11:44:29.217916+00:00
4,2021-07-30T11:44:43.598702+00:00
5,2021-08-03T20:53:48.482419+00:00
6,2021-08-04T22:19:52.810907+00:00
7,2021-08-05T17:25:29.646553+00:00
8,2021-08-05T17:25:33.425523+00:00
9,2021-08-05T17:26:22.169369+00:00
10,2021-08-05T17:50:26.585485+00:00
11,2021-08-10T16:20:38.839126+00:00
12,2021-08-10T17:38:00.557487+00:00
13,2021-08-11T16:09:30.470890+00:00
14,2021-08-11T16:09:34.164904+00:00
15,2021-08-12T15:43:18.819458+00:00
16,2021-08-12T16:19:30.123575+00:00
18,2021-08-15T12:55:20.660137+00:00
24,2021-08-18T18:21:12.153480+00:00
25,2021-08-18T19:18:37.432911+00:00

The reason is sqlite3 database can not store timezone information as it does not support built-in date and/or time. And since the sample date contains timezone information, sqlite3 is unable to extract date from the datetime field, and showing None.
correct format for sqlite3
2021-11-29 12:40:20.021350

Related

Django-Postgres: how to group by DATE a datetime field with timezone enabled

I am having this problem with prostgresql and django:
I have a lot of events that were created on a certain date at a certain time which is stored in a datetime field created .
I want to have aggregations based on the date part of the created field. The simplest examples is: how many event are in each day of this month?.
The created field is timezone aware. So the result should change depending on the timezone the user is in. For example if you created 2 events at 23:30 UTC time on 2017-10-02 if you view them from UTC-1 you should see them on 3rd of October at 00:30 and the totals should add for the 3rd.
I am struggling to find a solution to this problem that works with a lot of data. So doing for each day and SQL statement is not an option. I want something that translates into:
SELECT count(*) from table GROUP BY date
Now I found a solution for the first part of the problem:
from django.db import connection
truncate_date = connection.ops.date_trunc_sql('day', 'created')
queryset = queryset.extra({'day': truncate_date})
total_list = list(queryset.values('day').annotate(amount=Count('id')).order_by('day'))
Is there a way to add to this the timezone that should be used by the date_trunc_sql function to calculate the day? Or some other function before date_trunc_sql and then chain that one.
Thanks!
You're probably looking for this: timezone aware date_trunc function
However bear in mind this might conflict with how your django is configured. https://docs.djangoproject.com/en/1.11/topics/i18n/timezones/
Django 2.2+ supports the TruncDate database function with timezones
You can now do the following to :
import pytz
east_coast = pytz.timezone('America/New_York')
queryset.annotate(created_date=TruncDay("created", tzinfo=east_coast))
.values("created_date")
.order_by("created_date")
.annotate(count=Count("created_date"))
.order_by("-created_date")

Group objects by dates

clicks = SellerClick.objects.extra({'date' : "date(timestamp)"}).values('date').annotate(count=Count('timestamp'))
The model has a datetime field called timestamp that was are using. I first, convert the datetime field to just a date field. Then the rest is guessing. I need to group by, and then count how many objects are of each date.
So the desired result would be a date, then a count, based on how many objects have that date in the timestamp field.
I prefer to use annotate over extra
from django.db.models.expressions import RawSQL
SellerClick.objects.annotate(
date=RawSQL('date(date_joined)',[]),
).values('date').annotate(count=Count('date')))
You've got everything but an initial queryset there. The extra sql you're passing doesn't include a select so you need to give it something to act on.
clicks = SellerClick.objects.all()
.extra({'date' : "date(timestamp)"})
.values('date')
.annotate(count=Count('timestamp'))
Ref: StackOverflow: Count number of records by date in Django

Unable to retrieve data in django

I am writing a weblog application in django. As part of this, I have a view function that fetches an object from the database corresponding to a single blog post. The field that I am using to query the database is the published date (pub_date) which is of type DateTime (Python). I have a MySQL database and the type of the column for this field is datetime. But I am not able to fetch the object from the database though I am passing the correct date attributes. I am getting a 404 error.The following is my view function:
def entry_detail(request,year,month,day,slug):
import datetime,time
date_stamp = time.strptime(year+month+day,"%Y%b%d")
pub_date = datetime.date(*date_stamp[:3])
entry = get_object_or_404(Entry,pub_date__year=pub_date.year,pub_date__month=pub_date.month,pub_date__day=pub_date.day,slug=slug)
return render_to_response('coltrane/entry_detail.html',{'entry':entry})
The following is the URL of the individual post that I want to fetch:
http://127.0.0.1:8000/weblog/2014/oct/28/third-post/
And this is how the pub_date column value for the third-post in the database looks like:
2014-10-28 13:26:39
The following is the URL pattern:
url(r'^weblog/(?P<year>\d{4})/(?P<month>\w{3})/(?P<day>\d{2})/(?P<slug>[-\w]+)/$','coltrane.views.entry_detail'),
You're doing some odd things here: you're converting to a time, then converting that to a datetime.date, then extracting the year, month and day as integers and passing them to the query. You could bypass almost the whole process: the only thing you need is to convert the month, the other parameters can be passed directly:
month_no = datetime.datetime.strptime(month, '%b').month
entry = get_object_or_404(Entry, pub_date__year=year, pub_date__month=month_no, pub_date__day=day, slug=slug)

Django usage of DATETIME in SQL table django_admin_log

Why doesn't Django in SQL table django_admin_log use TIMESTAMP instead of DATETIME for attribute action_time? I mean according to this answer it should be using TIMESTAMP.
LogEntry's action_time field is a models.DateTimeField, which (perhaps unsurprisingly) is stored as a DATETIME field.
I think you've misunderstood the answer you linked - it recommends using DATETIME, not TIMESTAMP:
If you meant that you want to decide between using a UNIX timestamp or a native MySQL datetime field, go with the native format. You can do calculations within MySQL that way ("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)") and it is simple to change the format of the value to a UNIX timestamp ("SELECT UNIX_TIMESTAMP(my_datetime)") when you query the record if you want to operate on it with PHP.

how to extract date from a datetime field inside a filter in django

I have used this query in my view..
temp2=transaction.objects.filter(user_id=client_obj,Date_of_trans.date()=rec_var1)[0].Trans_Amount
I need to compare a datetime field present in my model named Date_of_trans to a variable received from user but the code is not working... what query should be written?
This is basically a sql query. So you should think like that. How can you do this in sql. I mean what condition will you apply in sql. For finding records of particular date with datetime field you should check records between start of the day to end of the day.
try this
from datetime import datetime, time
temp2=transaction.objects.filter(user_id=client_obj,Date_of_trans>datetime.combine(rec_var1, time(0,0,0)), Date_of_trans <= datetime.combine(rec_var1, time(23,59,59)) )[0].Trans_Amount
The above code is written taking into consideration that rec_var1 is a date() object.
Here you check all transactions between start of the day, till end of the day. I think this will resolve your problem.
I've use datetime.combine function which combines date and time object to form datetime object which is required here.
Thanks