django error validation datetime.datetime, tz format - python

I'm trying to filter publications by date, with this code but try it, I get this error
from datetime import datetime, timedelta
from_date = datetime.now() - timedelta(days=7)
data = Entry.objects.filter(date_publication=[from_date, datetime.now()])
[u"'[datetime.datetime(2014, 2, 24, 18, 27, 9, 451000), datetime.datetime(2014, 2, 17, 18, 27, 9, 451000)]' tiene un formato incorrecto. Debe ser del tipo YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]."]
class Productos(models.Model):
...
date_publication = models.DateTimeField(auto_now=True)
...
help me! :)

You can try with:
data = Entry.objects.filter(date_publication__gte=from_date, date_publication__lte=datetime.now())

Related

Django query to filter date range

I have a model which contains date range i want to filter the data based on the range date
that is i want the data who's date range is 90 days from today's date.
class MyModel(models.Model):
name = models.CharField(max_length=255)
start_end_date = ranges.DateTimeRangeField(validators=
[validate_range_date_time])
so when we select the start date on page the end date will popoulate the same date but i cannot concatenate filter just by today date + timedelta(days=90) this is one single date and the field is date range, so how can i filter the date range data which is 90 days from now.
the model stores start_end_date as
'start_end_date': DateTimeTZRange(datetime.datetime(2022, 11, 29, 9, 15), datetime.datetime(2022, 11, 29, 10, 0),
Mymodel.objects.filter(start_end_date__contains=timezone.now() + timezone.timedelta(days=90))
timezone.now() + timezone.timedelta(days=90) = datetime.datetime(2022, 11, 29, 22, 52, 7, 759648)
the query is giving empty set
I think you could design the model more easily.
class MyModel(models.Model):
name = models.CharField(max_length=255)
start_date = models.DateTimeField()
end_date = models.DateTimeField()
Then you can find objects like the following.
target_time = timezone.now() + timezone.timedelta(days=90)
MyModel.objects.filter(start_date__lte = target_time).filter(end_date__gte = target_time)
As it's a DateTimeRangeField, I think your result can be achieved by using startswith and endswith just like that:
max_date = timezone.now() + timezone.timedelta(days=90)
MyModel.objects.filter(start_end_date__startswith__gte=timezone.now(), start_end_date__endswith__lte=max_date)
Hope it helps!
I haven't used this field myself, but in base of what i read from documentaition, it should be like this:
from psycopg2.extras import DateTimeTZRange
Mymodel.objects.filter(
start_end_date__contained_by=DateTimeTZRange(
timezone.now(),
timezone.now() + timezone.timedelta(days=90)
)
)
to check if any start_end_date field is in 90 days from now, you should also pass a datetime range.
edited:
from psycopg2.extras import DateTimeTZRange
Mymodel.objects.filter(
start_end_date__contained_by=DateTimeTZRange(
timezone.now(),
timezone.now() + timezone.timedelta(days=90),
start_end_date__lower_inc=False
)
)

Django Timezone Configuration

My django project is correctly enable the timezone in settings.
However, the datetime field of Django ORM object is a naive datetime object as shown in Block 3.
The expected result should be same as the output of Block 4 without any manually conversion.
In [1]: from django.conf import settings
...: settings.USE_TZ, settings.TIME_ZONE
Out[1]: (True, 'Asia/Hong_Kong')
In [2]: from qms.models import Quota
In [3]: q = Quota.objects.get(pk=1)
...: q.create_date, q.write_date
Out[3]:
(datetime.datetime(2021, 3, 10, 17, 37, 42, 489818),
datetime.datetime(2021, 3, 10, 17, 37, 42, 489818))
In [4]: from django.utils import timezone
...: timezone.make_aware(q.create_date,timezone.utc), \
...: timezone.make_aware(q.write_date, timezone.utc)
Out[4]:
(datetime.datetime(2021, 3, 10, 17, 37, 42, 489818, tzinfo=<UTC>),
datetime.datetime(2021, 3, 10, 17, 37, 42, 489818, tzinfo=<UTC>))
Record in SQL
Column
value
id
1
create_date
2021-03-10 17:37:42.489818+00
write_date
2021-03-10 17:37:42.489818+00
name
email
Django Model Definition
class Quota(models.models):
name = models.CharField(max_length=255)
create_date = models.DateTimeField(auto_now_add=True)
write_date = models.DateTimeField(auto_now=True)
The PostgreSQL database schema and settings, Table "public.qms_quota"
Column
Type
Modifiers
id
integer
not null default nextval('qms_quota_id_seq'::regclass)
create_date
timestamp with time zone
not null
write_date
timestamp with time zone
not null
name
character varying(255)
not null
SHOW TIMEZONE;
TimeZone
----------
UTC
Questions
How can I get the timezone-aware datetime object directly without any conversion?
Or the manual conversion is expected ?
The root-cause is a bug from a connection pool library django_postgrespool2==2.0.1.
When you use the your connection engine with "django_postgrespool2", it will NOT correctly handle the timezone settings. Releated Issue
TLDR: use engine django.db.backends.postgresql
You can use django.utils.timezone.localtime to convert the datetime received from the DB to localtime:
from django.utils.timezone import localtime
q = Quota.objects.get(pk=1)
print(localtime(q.create_date), localtime(q.write_date))

How to use timedelta with timezone.now as default?

In Django models, How to increment the date field using timezone.now?
working:
end_date = models.DateTimeField(default=timezone.now() + timezone.timedelta(days=365))
Not Working
end_date = models.DateTimeField(default=timezone.now + timezone.timedelta(days=365))
I think timezone.now is a function which runs every time when the object is created. so that error occurs.
You could use a function:
def f():
return timezone.now() + timezone.timedelta(days=365)
...
end_date = models.DateTimeField(default=f)
The current time in that timezone is the added with the timedelta anytime a new end_date is created by default:
>>> from django.utils import timezone
>>> from datetime import timedelta
>>> def f():
... return timezone.now() + timezone.timedelta(days=365)
...
>>> f()
datetime.datetime(2018, 6, 25, 19, 42, 49, 761389, tzinfo=<UTC>)
>>> f()
datetime.datetime(2018, 6, 25, 19, 43, 2, 953158, tzinfo=<UTC>)
Sample run with Django:
In [1]: from testapp import models
In [2]: models.Test.objects.create().date_added
Out[2]: datetime.datetime(2018, 6, 25, 20, 5, 28, 316214, tzinfo=<UTC>)
In [3]: models.Test.objects.create().date_added
Out[3]: datetime.datetime(2018, 6, 25, 20, 5, 33, 114624, tzinfo=<UTC>)
A good approach would be to use the post_save signal. Import it with
from django.db.models.signals import post_save and then create a handler function like this:
def handler_function(sender, instance, created, **kwargs):
if sender == YourModel and created:
instance.end_date = timezone.now() + timezone.timedelta(days=365)
instance.save()
post_save.connect(handler_function, sender=YourModel)
This will work for sure, I hope this also applies to your case. Let me know if you need further help!

Django get months from models.DateTimeField

Is it possible to filter a models.DateTimeField but only get the month in the filter object?
The field is:
time_stamp = models.DateTimeField(
default=timezone.now)
When I filter it, this is what I get:
[datetime.datetime(2016, 9, 22, 15, 2, 48, 867473, tzinfo=),
datetime.datetime(2016, 9, 22, 15, 4, 22, 618675, tzinfo=),
datetime.datetime(2016, 9, 22, 15, 5, 20, 939593, tzinfo=)]
The filter returns 3 rows, but clearly there is too much information. I only require the months, and maybe the year.
How can I achieve this?
Any help or direction would be appreciated,
Thanks
If you are using django 1.10.x there is Extract db function
from django.db.models.functions import Extract
months = MyModel.objects.annotate(month_stamp=Extract('time_stamp', 'month')).values_list('month_stamp', flat=True)
For django 1.9.x
from django.db.models import Func
def Extract(field, date_field='DOW'):
template = "EXTRACT({} FROM %(expressions)s::timestamp)".format(date_field)
return Func(field, template=template)
months = MyModel.objects.annotate(month_stamp=Extract('time_stamp', 'month')).values_list('month_stamp', flat=True)
You can use propety:
Class your_model(models.Model):
time_stamp = models.DateTimeField(
default=timezone.now)
#property
def _get_year(self):
return self.time_stamp.strftime("%Y-%m")
year = property(_get_year) #EDIT

django postgresql - extra datetime

In my project I have object with datetime field
startdate = models.DateTimeField(default="1999-01-01 00:00:00")
I need create new object and send datetime = "2015-12-9"
calen = models.calendar()
calen.startdate = datetime.strptime(request.POST["date"], "%Y-%m-%d")
calen.save()
In this object I see
calen.startdate => datetime.datetime(2015, 12, 9, 0, 0)
all right.
in pqAdmin3, postgres DB this field = "2015-12-09 08:00:00+02"
wrong 8 hours!!!! ->6+2
When I select this object calen.startdate
datetime.datetime(2015, 12, 9, 6, 0, tzinfo=<UTC>)
extra 6:00!!!!
I tried to make a complete date, now(),but all the same is extra 6 hours
Do not use django.utils.datetime for database fields. Use timezone instead.
from django.utils import timezone
now = timezone.now()

Categories

Resources