How to convert a string into a localised date in django - python

We are doing an AJAX call in Django, where a user enters a date and a number, and the AJAX call looks up if there already is a document with that number and date.
The application is internationalised and localised. The problem is how to interpret the date sent by AJAX into a valid Python/Django date object. This has to be done using the current users locale, ofcourse.
One solution I found does not work:
Django: how to get format date in views?
get_format() returns a string (in our case j-n-Y), but strftime() expects a format string in the form of %j-%n-%Y.
Why the Django format is different from the stftime() format beats me, FYI we're using Django 1.5 currently.
I think the problem is that in all examples I could find, the dates are already date objects, and Python/Django just does formatting. What we need is to convert the string into a date using the current locale, and THEN format it. I was figuring this would be a standard problem, but all of the possible solutions I found and tried don't seem to work...
Thanks,
Erik

Submitting a ticket to Django gave me a clue to the answer.
You can convert a specific type of data into an object by passing it through the corresponding field and calling to_python(). In my case with a date it would be like so:
from django.forms.fields import DateField
field = DateField()
value = request.GET.get('date', '')
formatted_datetime = field.to_python(value)
Erik

Sounds to me it would make your life easier to let the user select the date from a calendar, instead of typing its string representation.
This way you know exactly what you're getting.

If you know the format, then you should be able to use datetime.strptime .
Have used it in code successfully in conjunction with ajax calls.
See here for more information: http://docs.python.org/2/library/datetime.html#strftime-strptime-behavior

Related

Django time reformat

I have a pair of time field inputs in my Django forms. I wanted to create the form in a way that allows the user to enter the time in whichever format they would like and the program will reformat to the correct type.
Not sure what is the best way to go.
Using Django validation but the user does not get feedback about input.
Using html5 time input sounds promising but it has poor support for IE, which users are expected to use.
Javascript/jquery but the user can change the Javascript code to bypass client-side validation.
Any suggestions?
You should check arrow.
Arrow is a Python library that offers a sensible, human-friendly approach to creating, manipulating, formatting and converting dates, times, and timestamps

Why python datetime replace timezone is returning different timezone?

I am working on Python/Django project. I am trying to let user select date and time using jQuery plugin datetimepicker add-on. So when I select now option and post data django is saving the time in UTC offset. This is what is saved in database, 2017-03-30 13:38:00+00:00. I need to convert this time from user's timezone and save it in system as utc. Because later I will have script running which will look for data in database which is less than the utc time.
Actually the script is to let user post information on website and let them chose the publish date and time. So for example, If use posted an article which will be published on April 2nd 1pm Chicago time, I don't want other users to read the article before this time. So people around the world can read article as soon as it is April 2nd and 1PM in Chicago. So how can I make this functionality work?
My solution was to get the time and remove it's timezone information using replace(tzinfo=pytz.timezone('America/Chicago')) and when I print the time, I am getting 2017-03-30 13:38:00-05:51. The actual offset right now is -05:00. Can anyone help me to and tell me what I am doing wrong?
What I am doing for form is that I have publish_date object in my model and I am using django forms to create form. I have added class as an attribute in it and using jquery plugin,
$('.datepicker').datetimepicker({
timeFormat: 'HH:mm',
stepHour: 1,
stepMinute: 1,
});
So when User submits the form, on post method this my code,
form = PublishForm(request.POST)
if form.is_valid():
f = form.save(commit=False)
f.created_by_user_id = request.user.id
f.save()
and than to get the date all I am doing is f.publish_date and the other options I have used lice replace and localize are pretty standard.
Thanks
As noted in the comments, you appear to have two problems. First is that the datetimepicker is saving a date and time with a UTC timezone offset, when it should be applying a different timezone or leaving off the timezone offset entirely. Second is that pytz is using the wrong offset.
I don't know how to fix the first problem, but I can help you with the second. You need to use pytz's localize function. This only works when the datetime doesn't have a timezone attached, but since you know the timezone is incorrect anyway you can delete it first.
tz = pytz.timezone('America/Chicago')
dt = tz.localize(dt.replace(tzinfo=None))
The naming of the datetime replace(tzinfo = ...) function is unfortunate. In fact, its behaviour is random. Do not use this!
Mark's answer is the way to go. Use localize.

Django - in the model, created_at is a UNIX timestamp

I am new to Django. I would have better grasp of this in Rails but am not familiar enough with all the libraries and converstions in Python / Django.
I have a model:
class Status(models.Model):
created = models.DatetimeField(auto_now_add=True)
This results in the format:
"created": "2017-01-06T22:21:51.531723Z"
I was hoping to see if before saving to the DB that it stores as a UNIX value?
This looked promising https://stackoverflow.com/a/34843855/3007294 but can't get it working. Every time I try to create a Status object, I get this error:
Datetime has wrong format. Use one of these formats instead: YYYY-MM-DDThh:mm[:ss[.uuuuuu]][+HH:MM|-HH:MM|Z].
My intentions are to not have to enter this every time a Status object is created.
Thanks -
My intentions are to not have to enter this every time a Status object is created.
This is already taken care of with the auto_now_add=True option. When you create a Status object, the created field will be populated with the current datetime.
I was hoping to see if before saving to the DB that it stores as a UNIX value?
You can convert the datetime value from Status.created to a Unix timestamp anytime required. Storing it in the default database datetime format (which is what DatetimeField does) is generally preferred to storing it as a timestamp, which is just an integer.
However, the library used in the example you provided, django-unixdatetimefield, states that "UnixDateTimeField is based on the implementation of the standard Django DateTimeField, making it 100% compatible with all features and options it supports." So, you should be able to provide the auto_now_add=True option to that field.

Which datatype in Django model to be used to save HTML5 type "month" in database

I have a HTML form with field which takes input as month
<input type='month' name="last_appraisal" id='txtLastAppraisal' value='2013-12' />
In my Django model this field is defined as
last_appraisal = models.DateField(blank=True, null=True)
When I try to save this value (received from request.POST) in database then I get format error.
last_appraisal = request.POST.get('last_appraisal','')
if last_appraisal != '':
mymodel.last_appraisal = last_appraisal
mymodel.save()
ERROR: raise exceptions.ValidationError(msg)
ValidationError: [u"'2013-01' value has an invalid date format. It must be in YYYY-MM-DD format."]
I know I can achieve this by adding a default day(maybe 01) to this input month and then save into the database. And while fetching back this value I can re-format it like "YYYY-MM" and send it back to template.
But I want to know if there's any better way to achieve this. I am using Django 1.5.1 and Python 2.7.
EDITED:
After reading all the responses it is clear that Django doesn't have built-in support for this format. Now I have few choices
My way to add day into date field.
As suggested by #Odif to take database field as 'CharField'
As suggested by #Ghopper21 to create a Custom Django field
My preference will be the choice1 because using this
I don't have to write some extra complex code compare to choice3.
I get the flexibility to use this field in table searches like 'find all candidates who got their appraisal in Jun 2013' which I loose if I go for chioce2.
Don't know whether my choice is good or bad but considering the size of project and time to complete it I think this will be the best choice. Please comment if you think this is absolutely rubbish or if you are in favor of this approach.
There are two issues here: Django doesn't have a built-in way to deal with month/year-only dates, and nor does Python.
If you are ok with a convenient way to translate the month/year-only dates into full dates with the day set to 1, but just don't want to have to do this manually in your view code every time, you can encapsulate that logic in a custom Django widget, which is a component for translating between the Django field representation (in this case a DateField) and the HTML input field.
If you need to have the underlying Python representation of the date to be month/year-only in a first class way, I'd suggest looking into the excellent Python library dateutil's relativedelta class -- which allows you to specify things like relativedelta(year=2013, month=12). If you want to use that, you'd then have to create a custom Django model field that translates between relativedelta instances and database storage via serialization. You'd then still need a custom widget for the HTML side of things.
Use models.CharField. DateField and DateTimeField expect date and datetime object respectively. Since '2013-01' cannot be coerced into either, then use CharField. Or use integerfield and just post month.

Django model TimeField views.py cannot select hour or minute

When using a TimeField in a Django model I wish to be able to perform a query in a view, using the hour and minute elements of the TimeField separately.
However, when I do so, if I run the view I receive an error message that the __hour (or __minute) does not exist (see code below):
scheduleItems = DEVICESCHEDULE.objects.filter(time__hour = nowHour)
If I change the model to use a DateTimeField rather than a TimeField, I am able to use the __hour and __minute options.
I would prefer to keep the field type as a TimeField, as I only need a time to be input and inputting a date (even if it is ignored) is confusing to the user.
Thanks in advance!
Seem like the date/time related lookups only works with dates and datetimes, not the time fields, although seems like it would be a nice feature to have as well.
Have you thought about raising a ticket maybe?
Maybe you can consider this as a replacement:
DEVICESCHEDULE.objects.extra(where=['SUBSTR(time, 1, 2)=%0.2d'], params=[nowHour])
DEVICESCHEDULE.objects.extra(where=['SUBSTR(time, 4, 2)=%0.2d'], params=[nowMinute])

Categories