The time that is being inserted in database is default UTC, not the timezone based time..I do not understand why is this happening, even though I am particularly specifying, in the query, the time that I want to be inserted.
In my Model I have
class leave(models.Model):
date_created = models.DateTimeField(auto_now_add=True)
In my settings I have
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
In my views i am setting timezone based on employee country
if employees.objects.get(emp_id=request.user.username).emp_loc == 'IND':
tzone=pytz.timezone('Asia/Calcutta')
elif employees.objects.get(emp_id=request.user.username).emp_loc == 'MLA':
tzone=pytz.timezone('Asia/Manila')
elif employees.objects.get(emp_id=request.user.username).emp_loc == 'MPLS':
tzone=pytz.timezone('CST6CDT')
And then I am creating leave and updating timezone based on country
new_leave = leave.objects.create(employee=employees.objects.get(emp_id = userid.emp_id), start_date=sdt, end_date=edt, ltype=ltyp, message=des,date_created=datetime.now(tzone))
new_leave.save()
Thanks in Advance.
You can create a middleware that handles the conversion of date and time,
import pytz
from django.utils import timezone
from django.utils.deprecation import MiddlewareMixin
class TimezoneMiddleware(MiddlewareMixin):
def process_request(self, request):
tzname = request.session.get('django_timezone')
if tzname:
timezone.activate(pytz.timezone(tzname))
else:
timezone.deactivate()
and then you can as easily create the view with the conditions that you indicated earlier.
Best if you read the documentation as Kevin suggested.
Related
Not able to change TImezone in Trunc functions. It always take timezone from settings.py
import pytz
ind = pytz.timezone('Asia/Calcutta')
Query:
queryset = Order.objects.annotate(date=TruncDate('created_at', tzinfo=ind)).values('date')
While inspecting sql query by queryset.query
SELECT DATE(CONVERT_TZ(`nm_order`.`created_at`, 'UTC', UTC)) AS `date` FROM `nm_order`
Reference: Trunc in Django
But for Extract, it's get working
ORM:
queryset = Order.objects.annotate(date=ExtractDay('created_at',tzinfo=ind)).values('date')
Query:
SELECT EXTRACT(DAY FROM CONVERT_TZ(`nm_order`.`created_at`, 'UTC', Asia/Calcutta)) AS `date` FROM `nm_order`
Am I miss something in Trunc ?
TimeZone Settings in my settings.py
IME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
You need to use TruncDay() instead of TruncDate. In the usage example just below that section of the documentation you'll see the difference between the two.
TruncDate does not take a timezone option - it uses the current timezone and gives you the date in that timezone.
I think the distinction between the two is that TruncDate returns a DateField which by definition cannot be timezone-aware. TruncDay on the other hand returns a DateTimeField(with time portion set to 00:00:00), which can be timezone aware.
From django 3.2, TruncDate now accepts tzinfo parameter. https://docs.djangoproject.com/en/dev/ref/models/database-functions/#django.db.models.functions.TruncDate
After Inspecting TruncDate Class looks like it doesn't have timezone option
class TruncDate(TruncBase):
kind = 'date'
lookup_name = 'date'
#cached_property
def output_field(self):
return DateField()
def as_sql(self, compiler, connection):
# Cast to date rather than truncate to date.
lhs, lhs_params = compiler.compile(self.lhs)
tzname = timezone.get_current_timezone_name() if settings.USE_TZ else None
sql, tz_params = connection.ops.datetime_cast_date_sql(lhs, tzname)
lhs_params.extend(tz_params)
return sql, lhs_params
I want to use django-datetime-widget in Polish language. But following instruction from project's github give me error. My situation is:
form:
class add_test_form(forms.Form):
test_date_finish = forms.DateTimeField(label="Termin zakonczenia testu", widget=DateTimeWidget(usel10n=True, bootstrap_version=3), localize=True)
view:
test = Test(test_date_start = request.POST['test_date_start'])
test.save()
model:
class Test(models.Model):
test_date_finish = models.DateTimeField()
settings.py:
LANGUAGE_CODE = 'pl-pl'
TIME_ZONE = 'Europe/Warsaw'
USE_I18N = True
USE_L10N = True
USE_TZ = True
I got ValidationError in Polish which translates into:
[...] value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[." "uuuuuu]][TZ] format.
Your date-time format isn't right, you should set it. This code in the project's docs may help you with that. Probably you should put this on your settings.py and change the format part according to your datetime format.
dateTimeOptions = {
'format': 'dd/mm/yyyy HH:ii P',
'autoclose': True,
'showMeridian' : True
}
widgets = {
#NOT Use localization and set a default format
'datetime': DateTimeWidget(options = dateTimeOptions)
}
I am following this to add a custom validation on my modelform and it is working...mostly.
My code:
from django import forms
from django.utils.translation import ugettext_lazy as _
from datetime import datetime, timedelta
from datetimewidget.widgets import DateWidget
from .models import User
class UserForm(forms.ModelForm):
class Meta:
# Set this form to use the User model.
model = User
# Constrain the UserForm to just these fields.
fields = ("birthdate")
widgets = {
'birthdate': DateWidget(attrs={'id':"id_birthdate"}, bootstrap_version=3)
}
def clean_birthdate(self):
birthdate = self.cleaned_data["birthdate"]
min_time = datetime.strptime('1920-01-01', '%Y-%m-%d').date()
delta = birthdate - min_time
if delta <= timedelta(days=0):
raise forms.ValidationError(_("We don't accept people born before 1920"))
return birthdate
It raises the error like intended until 1900-01-01, but once i enter to 1899 it doesn't.
I am not sure what may be causing it. I am using DateTimeWidget.
The error i am getting is:
year=1899 is before 1900; the datetime strftime() methods require year >= 1900
I checked the result of the comparison and it is working as intended (False for years below 1920).
In short model is being updated and error is not being raised when it should.
This is a limitation of python's built-in strftime function. It does not support dates prior to 1900. Try this instead
if birthdate.year < 1920:
raise forms.ValidationError(_("We don't accept people born before 1920"))
I'm using Django 1.6 and I have to display a date. The timezone is Guayaquil (-05:00) and I have to get the date as:
{
'fecha': partido.fecha.strftime("%d %B"),
'hora': partido.fecha.strftime("%T"),
}
Expecting: '13 Junio' and '14:00:00' respectively, since that's the time saved and in Guayaquil timezone.
However what I get is the same time in UTC and months names in english: '13 June' and '19:00:00'.
What can I do to solve this issue?
You have to configure you time zone in your Django Settings
Choices can be found Here
Check in your settings.py:
TIME_ZONE = 'America/Guayaquil'
USE_I18N = True
USE_L10N = True
USE_TZ = True
LANGUAGE_CODE = 'es'
I want to disable django fields for 6 months after the date of update. I have saved update_time to a table.
updated_time = a.update_time
disabled_time = a.update_time + timedelta(180)
I want to diable field that updated:
self.fields['first_name'].widget.attrs['readonly'] = True
How can I disable self.fields['first_name'].widget.attrs['readonly'] = True for disabled_time?
Thanks in advance
You can compare, and substract basic datetime objects and make some check at form initialization time:
from datetime import timedelta, datetime
...
class FooForm(ModelForm):
def __init__(self, *args, **kwargs):
super(FooForm, self).__init__(*args, **kwargs)
# check if we already have a saved object and it's not older than 180 days
if self.instance.pk and
(datetime.now() - self.instance.update_time) < timedelta(180):
self.fields['first_name'].widget.attrs['readonly'] = True
class Meta:
model = Foo
(Not really tested but should work as it is.)
Also note, that it is often convenient to keep update_time with auto_now set to True.