I have one model where each entry is stored and its created time is stored. The time is not a datetime object a timestamp. Timestamp field of model is shown below :
logged_at = models.CharField(_('log time'), max_length=128,
default=time.time)
If above field is datetime field then I can write an query which can group by records using datetime field like :
MyModel.objects.filter(type_='in').annotate(in_time=RawSQL('(date(logged_at))', [])).values('in_time', 'name').annotate(count=Count('name'))
But I am not able to query the timesatmp field in same way , It gives me the error date/time field value out of range
I have also tried to use functions like to_timestamp nut still no success
MyModel.objects.filter(type_='in').annotate(in_time=RawSQL('(date(to_timestamp(logged_at)))', [])).values('in_time', 'name').annotate(count=Count('name'))
Error : function to_timestamp(character varying) does not exist
Database I am using is Postgres
As #Willem mentioned in comment that timestamp must not be stored in CharField. So We can try to change type of field at runtime like given below.
MyModel.objects.filter(type_='in').annotate(in_time=RawSQL('(date(to_timestamp(logged_at::float)))', [])).values('in_time', 'name').annotate(count=Count('name'))
IN above query I have changed type of logged_at to float and it works fine for me, you can also change it to int.
Related
I want to store time as unix timestamp in my MYSQL database, I have django project with model:
date = models.DateField()
But I didn't find any models.Timestamp()
or anything similiar. Is there a way to create timestamp column for MYSQL Db in Django? I found some articles here on stack but they are 5+ years old so there might a be a better solution now.
In Django, one usually uses a DateTimeField [Django-doc] for that. It is a column that thus stores a combination of date and time.
One can let Django automatically intialize (or update) the timestamp if the record is constructed or updated with auto_now_add=True [Django-doc] to initialize it when the record was created, and auto_now=True [Django-doc] to update. So it is a common pattern to see a (base)model like:
class TimestampModel(models.Model):
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
such that subclasses of the TimestampModel thus have two extra columns created and updated that store the time when the object was created and last updated respectively.
A datetime column has a larger range, as is specified in the MySQL documentation:
The DATETIME type is used for values that contain both date and time
parts. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD hh:mm:ss' format. The supported range is '1000-01-01 00:00:00' to
'9999-12-31 23:59:59'.
The TIMESTAMP data type is used for values that contain both date
and time parts. TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.
I've Django model which has foreign keys associated with other models. Each model is having same field names(attributes) created_at and updated_at
In every django queryset results I'll be getting datetime values.
Model.objects.all().values('created_at')
But I want to format the datetime field to "DD-MM-YYYY HH:MM:SS" and trim down the milliseconds in the django query results.
If I use "extra" and and date_trunc_sql like the following command
dt = connection.ops.date_trunc_sql('day','created_date')
objects.extra({'date':dt}).values('date')
Which works fine. But If I query like the following, its raising ambiguous statement error.
objects.extra({'date':dt}).values('date', 'x', 'y', 'z')
How to overcome this problem?
Solved it via #Yannics answer at: https://stackoverflow.com/a/60924664/5804947
This also avoids using extra which should be "a last resort" due to Django docs.
from django.db.models import F, Func, Value, CharField
qs.annotate(
formatted_date=Func(
F('created_at'),
Value('DD-MM-YYYY HH:MM:SS'),
function='to_char',
output_field=CharField()
)
)
Got the solution.
data = list(Model.objects.extra(select={'date':"to_char(<DATABASENAME>_<TableName>.created_at, 'YYYY-MM-DD hh:mi AM')"}).values_list('date', flat='true')
It's not just tablename.attribute, it should be dbname_tablename.attribute when we have multiple databases(ambiguous)
which will result list of created_at datetime values trimmed to 'YYYY-MM-DD HH:MM' format.
I don't think values() function would anything related to formatting datetime result. But why does that bother you? Can't you convert them to proper format when you try to display them? If you try to render them in the template, django has template filter date for formatting your datetime value: https://docs.djangoproject.com/en/1.9/ref/templates/builtins/#date
I have search option which user input from front end.
search = {"Date":"2016-02-07","Status":"pass" }
Then I am mapping with those values with column names in DB.
query_to_field_mapping = {"Date": "date","Status": "result"}
query = {query_to_field_mapping[key]: value for key, value in search.items()}
Now I have DateTimeField in DB. When I am using filter I am trying with below one:
result = Customer.objects.filter(**query)
Here am trying to filter as per date field & want to get the filtered record as well. I tried the same with no success .How can I proceed?
Any help ll be awesome!!!
I tried the some other question from SO: How can I filter a date of a DateTimeField in Django?
I couldn't get a way to solve my problem as there we are passing a column name 1 by 1 .But right now I am passing as dictionary.
Your approach is the correct one. The reason why it doesn't work is because you filter for equality of datetime field by providing a date string, therefore a 2016-02-07 date (your query param) does not equal 2016-02-07T12:32:22 (a possible value in the DB).
To overcome this situation, use one of the field lookups possibilities from the link of your own question. As a specific example, let's use a contains field lookup, like so:
query_to_field_mapping = {"Date": "date__contains","Status": "result"}
Thus, when passing the query_to_field_mapping to .filter(), it will look for the date within the datetime that you need.
Currently in our database the date field is entered as a string (ex: 11/7/2009). Is there anyway in my models.py file to convert this field from say a TextField to DateField so that in the Admin Console a user could select the date from the calendar view instead of having to enter it in manually? Perhaps parse it on the fly?
date = models.TextField()
convert to..
date = models.DateField()
Your best bet is to start storing the data correctly. In order to do this you'll want to alter the table to add a new field (in the database) with the date type. Parse the existing date data from the charfield into this new field and then finally alter the table to drop the charfield and rename the the temporary date field appropriately
This process could be simplified by using django-south to manage the migrations. You'll need 3 migrations: schemamigration to add the temporary field, datamigration to convert the data, schemamigration to drop the old column and rename the new one.
You could try using a custom form in the admin...you might be able to force the conversion at runtime, but it's really not a great idea since you really should be storing data correctly. I've used custom forms before in the admin, but not for this so I can't be sure if it would work.
After changing the column in MSSQL to type date we still were having the same issue. I should have also mentioned we were using pyodbc to help server our backend. The change we made was within the pyodbc code in the operation.py file. A type-except was added.
def convert_values(self, value, field):
.......
elif field and field.get_internal_type() == 'DateField':
try:
value = value.date() # extract date
#ADDED THE FOLLOWING TO CATCH THE ERROR
except AttributeError:
value = datetime.datetime.strptime(value, '%Y-%m-%d').date()
After we added this the django admin console was displaying the Calendar widget.
I'm having a bit of trouble with django's DateField model field. Shouldn't it be able to accept fiveDaysLater as a valid date object? When I try to add fiveDaysLater into the database, I get an error saying cannot add null value to date. However, the second I change the date field to a regular CharField, the fiveDaysLater value is added to the database with no problem. fyi if I print fiveDaysLater, I get 2011-09-28
My view:
def myView():
now = datetime.date.today()
fiveDaysLater = now + datetime.timedelta(days=5)
newDate = Speech(date = fiveDaysLater)
newDate.save()
My model
class Speech(models.Model):
date = models.DateField()
"However, the second I change the date field to a regular CharField..." Just a suspicion but if you made this change in your code, make sure to delete and recreated the Speech table using syncdb, otherwise, sqlite will not be aware of this change. (or you could change the datatype using sqlite exporer for firefox or something like that...)