6👍
The very first thing I noted here is, you are using serializers.DateTimeField
–DRF doc field for a year representation, where the year always will be a positive integer.
Regarding the timezone issue, Django uses the TIME_ZONE
settings while querying from the database. Here is the minimal SQL query in postgress that happens when you do so,
SELECT a,b,c,DATE_TRUNC('year', "tracking_table"."created_at" AT TIME ZONE 'YOUR_TIME_ZONE_VALUE') AS "year" FROM "tracking_table
But, fortunately, you can specify the target timezone (in your case, its UTC) with the help of tzinfo
parameter in the TruncYear
class.
Example
import pytz
Tracking.objects.annotate(year=TruncYear('created_at', tzinfo=pytz.UTC))
To show year in the json reponse, change your serializer as,
class TimeseriesYearSerializer(serializers.ModelSerializer):
venue = VenueTSSerializer(read_only=True)
year = serializers.IntegerField(read_only=True, source='year.year')
count = serializers.IntegerField(read_only=True)
class Meta:
model = Tracking
fields = ['venue', 'year', 'count']
References
0👍
I’ve checked sources of Django Rest Framework and it looks like it uses “current timezone” by default for DateTimeField
but you can set it in a force manner by passing default_timezone
equal to "pytz.timezone('Zulu')"
. This way it will return the field value in the required timezone.
I’ve played with that a bit and for me it works as expected. For example for Europe/Moscow
for my test serializer (in my project) I have output like
{
"id": 1,
"title": "test 123",
"level": 0,
"slug": "test-123",
"icon_code": "123",
"image": null,
"brand": false,
"children": [],
"created_at": "2019-12-09T01:55:08.438442+03:00"
}
And for Zulu
timezone I have it like
{
"id": 1,
"title": "test 123",
"level": 0,
"slug": "test-123",
"icon_code": "123",
"image": null,
"brand": false,
"children": [],
"created_at": "2019-12-08T22:55:08.438442Z"
}
My test field declaration is
created_at = serializers.DateTimeField(format='iso-8601', default_timezone=pytz.timezone('Zulu'))
It seems like in your source code you override “current timezone” but don’t set it to a default one or etc and that’s why it works right after the server restart and stops in a few hours (when a request sets the wrong timezone). So you have 2 ways to fix it – declare your fields as I did above using the
default_timezone
param or find where the current timezone value is changed). The easiest solution for the case, of course, is declaring the field timezone required but in general, of course, it should work without bugs 🙂
More information:
- https://github.com/encode/django-rest-framework/blob/95d4843abeecea96754a147f4f2cca33e620ad09/rest_framework/fields.py#L1199
- https://docs.djangoproject.com/en/3.0/topics/i18n/timezones/#selecting-the-current-time-zone
- https://www.django-rest-framework.org/api-guide/fields/#datetimefield (look at
default_timezone
param)
- [Django]-Django delete error message
- [Django]-Django — new field: How to set default callable for existing objects
- [Django]-How to return all records but exclude the last item