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"
Related
I have a Django search form with an optional fields. If the field is used, it should be validated in clean_{field_name}. However I keep getting '>' not supported between instances of 'NoneType' and 'datetime.date' Error when the field is left empty. When I do a Request URL:http://localhost:8000/dockets/p_CentralGrocers/ (so no query parameters are passed at all), the cleaned_data parameter still has a blank item for the field name, which leads to a datetime comparison with a blank field which causes the error. What is the best way to handle optional fields in the cleaning process?
1 from django import forms
2 from django.core.exceptions import ValidationError
3 from django.utils.translation import ugettext_lazy as _
4 import datetime
5
6 class SearchDocketForm(forms.Form):
7
8 from_date = forms.DateField(help_text="Enter start date for search", required=False)
9 to_date = forms.DateField(help_text="Enter to date for search", required=False)
10
11 def clean_from_date(self):
12 data = self.cleaned_data['from_date']
13 if not data return ''
14
15 # check if date is in the past
16 if data > datetime.date.today():
17 raise ValidationError(_('Invalid date - from date in the future'))
18 return data
First, I Believe
'>' not supported between instances of 'NoneType' and 'datetime.date'
is an issue with the parsing.
The Data will be simply String when you post it.
eg: "01/01/2001" Will be the value of data if you're posting any values.
you must change it in to datetime object before comparison.
from datetime import datetime
.....
def clean_from_date(self):
data = self.cleaned_data['from_date']
if not data return ''
# Parse according to the format you're planning to post.
data = datetime.strptime(data, "%D %M %Y")
if data > datetime.date.today():
raise ValidationError(_('Invalid date - from date in the future'))
return data
Secondly, Verify if you have any
from_date = models.DateField(default=datetime.now())
set in models.py.
Tip:
Try print(data) before the if statement, it will give you contents of data in console.
I have a model:
def author_document_path(instance, filename):
return f"documents/{ instance.author.username }/%y/%m/%d/{filename}"
def author_blog_images(instance, filename):
return f"blog-images/{instance.author.username}/%y/%m/%d/{filename}"
class Blog(models.Model):
title = models.CharField(max_length=255)
# other fields
thumbnail = models.ImageField(upload_to=author_blog_images)
documents = models.FileField(upload_to=author_document_path)
What is the right way of passing f"blog-images/{instance.author.username}/%y/%m/%d/{filename}" in above two functions because these functions doesn't create year folders as 2019, month folder as 5 and day folder as 30. The directories look like this after uploading respected files and images:
this is not what I want I want it to look like:
Can you help me with this. Thank you so much.
You first fetch the current day, and then you can obtain the year, month and day attribute, like:
from datetime import date
def author_blog_images(instance, filename):
td = date.today()
return f'blog-images/{instance.author.username}/{td.year}/{td.month}/{td.day}/{filename}'
Here td.month and td.day will not have leading zeros (so it will be printed as 2019/5/30, not 2019/05/30). You can however use leading zeros in the format string, like:
from datetime import date
def author_blog_images(instance, filename):
td = date.today()
return f'blog-images/{instance.author.username}/{td.year}/{td.month:02d}/{td.day:02d}/{filename}'
or we can use a specific date formatting:
from datetime import date
def author_blog_images(instance, filename):
td = date.today().strftime('%y/%b/%d')
return f'blog-images/{instance.author.username}/{td}/{filename}'
We can also use, like #BearBrown says, Django's timezone.now [Django-doc]:
from django.utils import timezone
def author_blog_images(instance, filename):
td = timezone.now().strftime('%y/%b/%d')
return f'blog-images/{instance.author.username}/{td}/{filename}'
we can even pas an f-string as parameter to strftime, like #chepner says to replace certain parts of the before, and then let the strftime format the time with the format string produced by the f-string:
from django.utils import timezone
def author_blog_images(instance, filename):
return timezone.now().strftime(f'blog-images/{instance.author.username}/%y/%b/%d/{filename}')
There is however an edge case that should be taken into account here: if the instance.author.username, or the filename contains formatting parts like %d and %b, then the strftime will replace these with the day/month/... respectively. Although that is not very common, it is something to take into account.
Another thing that you should take into account is that when the author changes, or its username, the file will not be renamed, so it will still hold the name of the old author (or the old username of that author).
My views.py looks like that
def add_note(request):
registered = False
user = User.objects.get(username=request.user.get_username())
if request.method == 'POST':
note_form = NoteForm(data=request.POST)
if note_form.is_valid():
note = note_form.save()
note.save()
registered = True
else:
print(note_form.errors)
else:
pass
return render(request, 'note.html', {'note_form': NoteForm, 'registered': registered})
In my HTML i use <td><input type="datetime-local" id="id_data" name="data" ></td>
Data from this input is not valid because format is 2015-12-20T12:15, should be 2015-12-20 12:15
My question is:
It is possible to change data format in input? I need format like this 2015-12-20 12:15 (T switch to SPACE)
if not how change value of Data in views.py
You can specify what format does your datetime field accept from the form field in NoteForm, so that you can accept the default format:
data = forms.DateTimeField(input_formats=['%Y-%m-%d %H:%M', '%Y-%m-%dT%H:%M'])
If you insist on using your desired format, you might need to change your front end input to somehow have the format.
You can easily change the date format in your views usign embed python date functions. For example, you can use strptime and strftime, both datetime fuctions.
import datetime
new_date = datetime.datetime.strptime('07/12/2015', '%d/%m/%Y').strftime('%Y-%m-%d')
strptime receives your request date, and strftime convert that date to a custom format.
I've a booking form in my template that sends an email when it's submitted. In my database the datetime field is shown like: Oct. 6, 2015, 3:58 p.m. But when I get the email the datetime field is shown like: 2015-10-06 15:58:50.954102 How do i format it such that in the email it's shown exactly like how it's shown in the database?
models.py
class Booking(models.Model):
patient_name = models.CharField(max_length=1300)
phone = models.IntegerField(null=True, blank = True)
preference = models.CharField(max_length=150,null = True, blank = True) #morning,noon,night
doctor = models.ForeignKey(Doctor)
clinic = models.ForeignKey(Clinic,null=True, blank = True)
datetime = models.DateTimeField(auto_now=True, auto_now_add=True, blank = True, null = True)
def __unicode__(self):
return u"%s %s" % (self.patient_name, self.doctor)
views.py
lead = Booking(doctor_id=doctor.id, clinic_id=doctor.clinic.id, preference=preference, patient_name=patient_name, phone=phone)
lead.save()
body = "Request Made: " + str(lead.datetime) +" "
email = EmailMessage('Blah', body, to=[clinic.email])
email.send()
You can format datestrings using strftime
>>> from datetime import date
>>> dt = date(2015, 10, 6, 15, 58, 50)
>>> dt.strftime("%b. %-d %Y %-I:%M %p")
'Oct. 6 2015 2:12 PM'
There's a list of the codes for strftime at at http://strftime.org/
So in your view you would do something like
body = "Request Made: %s " % lead.datetime.strftime("%b. %-d %Y %-I:%M %p")
Thats not exactly how it's in the database, it's just what the tool you use to view inside the database, displays datetime.
However if you want your datetime to look exactly like that, use:
lead.datetime.strftime("%b. %-d %Y %-I:%M %p")
Here are some relevant sources:
https://docs.python.org/2/library/datetime.html#datetime.datetime
https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior
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