I need to use SHORT_DATETIME_FORMAT in view.
def manage_list(request):
user = User.objects.filter().order_by('date_joined')
usrs = []
for usr in user:
usrs.append({
_('First name'): usr.first_name,
_('Last name'): usr.last_name,
_('Email'): usr.email,
_('Active'): usr.is_active,
_('Superuser'): usr.is_superuser,
_('Staff'): usr.is_staff,
_('Joined date'): usr.date_joined.strftime(SHORT_DATETIME_FORMAT),
})
data = simplejson.dumps(usrs, indent=4)
return HttpResponse(data, mimetype='application/json')
usr.date_joined has a type of "date field" I think. I want to format this data according to django locale. so this string probably should help. I know that there's a template filter which does that I wan, but I want to format usr.date_joined in view only - saving django choosen locale.
If there's any other methods to do this please provide examples. in the end I just wanna have a formated date according to django locale which shows only date and time, I think this constant should do what the name says..
The django.utils.formats module is what you're looking for. The only reference I could find in the docs was in the Django 1.2 release notes.
Remember that the localisation will only work if the USE_L10N setting is True. You can use the date_format as follows.
from datetime import datetime
from django.utils import formats
date_joined = datetime.now()
formatted_datetime = formats.date_format(date_joined, "SHORT_DATETIME_FORMAT")
You might want to try using django.utils.dateformat.DateFormat
>>> from datetime import datetime
>>> dt = datetime.now()
>>> from django.utils.dateformat import DateFormat
>>> from django.utils.formats import get_format
>>> df = DateFormat(dt)
>>> df.format(get_format('DATE_FORMAT'))
u'April 23, 2013'
>>> df.format('Y-m-d')
u'2013-04-23'
More information using Python:
import django
help(django.utils.dateformat)
To use the Django date filter in a view use defaultfilters, e.g.:
from django.template import defaultfilters
formatted_date = defaultfilters.date(usr.date_joined, "SHORT_DATETIME_FORMAT")
Use localize shortcut.
>>> from django.utils.formats import localize
>>> from datetime import datetime
>>>
>>> print(datetime.now())
2016-12-18 19:30:35.786818
>>> print(localize(datetime.now()))
18 декабря 2016 г. 19:30
from django.utils.formats import date_format
date_format(usr.date_joined)
As of today what worked for me was setting USE_L10N to True.
Then import some utils :
from django.utils import (dateformat, formats)
Which can be used as such :
dateformat.format(my_date_object, formats.get_format('DATE_FORMAT'))
Note thate my_date_object should be a datetime object.
And there is a list of available formats :
DECIMAL_SEPARATOR
THOUSAND_SEPARATOR
NUMBER_GROUPING
FIRST_DAY_OF_WEEK
MONTH_DAY_FORMAT
TIME_FORMAT
DATE_FORMAT
DATETIME_FORMAT
SHORT_DATE_FORMAT
SHORT_DATETIME_FORMAT
YEAR_MONTH_FORMAT
DATE_INPUT_FORMATS
TIME_INPUT_FORMATS
DATETIME_INPUT_FORMATS
The name is pretty self explanatory...
see : https://github.com/django/django/blob/main/django/utils/formats.py
Related
I am using Django and have a problem with a date that I need to calculate.
The Variable data > test should be 17:00 and not 15:00. Why does this happen as soon as I format the date?
My timezone is Europe/Berlin. Changing the timezone has to effect to the time printing in test. It is always -2h
def date(req):
now = timezone.now()
model = MyModel.objects.filter(date__gt=now).first()
next = model.date
future = timezone.timedelta(hours=float(model.future)) #model.future = 1.5
open = next-future
date = next.strftime('%Y/%m/%d')
data = {
'next': next,
'date': date,
'time': open.astimezone(timezone.utc).strftime('%Y-%m-%d %H:%M:%S.%f'),
'test': open.strftime('%Y/%m/%d %H:%M:%S%z')
}
What I get:
next: 20. November 2021 18:30
date: 2021/11/20
time: 2021-11-20 15:15:00.000000
test: 2021/11/20 15:00:00+0000
https://docs.djangoproject.com/en/3.2/topics/i18n/timezones/#naive-and-aware-datetime-objects
You should use:
from django.utils import timezone
now = timezone.now()
Datetime isn't time-zone aware.
You cut the timezone info (the offset +02:00) with .strftime(). You need to include it with %z.
In case you want to convert it to a time string with the offset already added.
open.astimezone(timezone.utc).strftime('%Y-%m-%d %H:%M:%S.%f')
This works for me.
from django.utils import timezone
def date(req):
now = timezone.now()
model = MyModel.objects.filter(date__gt=now).first()
next = model.date
future = timezone.timedelta(hours=float(model.future)) #model.future = 1.5
open = next-future
date = timezone.localtime(open)
data = {
'next': date.strftime('%Y/%m/%d %H:%M:%S'),
'date': date.strftime('%Y/%m/%d'),
'time': date.strftime('%H:%M:%S'),
}
How can I translate a date in my views.py? If I try to translate it with gettext it returns me this error: an integer is required (got type str).
For translating a date i mean for example from english version (May 30, 2019) to italian one (30 Maggio 2019). I've to return the date in a json response. This is my code:
from django.utils.translation import gettext as _
...
#AutoLanguage #It's a middleware that enables i18n
date = datetime.date.today()
date_translated = _(date)
return JsonResponse({'date': date_translated})
Use locale.setlocale in your view:
import locale
def view_name(request):
QUERY_RESULT = MODEL_NAME.objects.get(pk=event_id) #ANY QUERY
try:
locale.setlocale(locale.LC_TIME, 'fr_FR.utf8') #your language encoding
except:
locale.setlocale(locale.LC_TIME, 'fr_FR')
translated_date = QUERY_RESULT.DATE.strftime("%A %d %B %Y") #<= format you want
You'll find the strftime formats in the datetime doc
for me it gives translated_date = "mardi 11 juin 2019"
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
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.
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"))