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
Related
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
)
)
Hi I want service old book sale service for university student
I create ItemPost model and when user post their books, ItemPost's deadline saved in deadline
from django.db import models
from django.conf import settings
from django.utils import timezone
def localtime():
return timezone.localtime(timezone.now())
class ItemPost(models.Model):
title = models.TextField(
)
created_at = models.DateTimeField(
default=localtime
)
is_deleted = models.BooleanField(
default=False,
verbose_name="삭제된 포스트",
)
# 마감날짜를 구하는 함수
def deadline_def(self):
year_of_item_created = self.created_at.year
if self.created_at.month <= 6:
return timezone.datetime(year_of_item_created, 6, 30)
else:
return timezone.datetime(year_of_item_created, 12, 31)
deadline = property(deadline_def)
# 등록된 학기가 끝난 포스트인지 확인
def is_ended_semester_def(self):
now = timezone.now()
if now > self.deadline:
return True
return False
is_ended_semester = property(is_ended_semester_def)
def __str__(self):
return self.title
I want compare item's deadline, timezone.now()
and return True or False
but I can't if I command item.is_ended_semester
TypeError: can't compare offset-naive and offset-aware datetimes
how can i solved this problem?
item.deadline
> datetime.datetime(2017, 6, 30, 0, 0)
timezone.now()
> datetime.datetime(2017, 7, 14, 8, 50, 57, 91304, tzinfo=<UTC>)
I solved my problem, using timezone.utc
# 마감날짜를 구하는 함수
def deadline_def(self):
year_of_item_created = self.created_at.year
if self.created_at.month <= 6:
return timezone.datetime(year_of_item_created, 6, 30, tzinfo=timezone.utc)
else:
return timezone.datetime(year_of_item_created, 12, 31, tzinfo=timezone.utc)
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!
On my Django site, I am saving a user's reactions so when a user clicks a button, I store it as a created time and when the user clicks it second time, I stored the time as a finish time and so forth. Here it is my model;
class UserStatus(models.Model):
STATUS_TYPES = (
('online', 'online'),
('offline', 'offline')
)
user = models.ForeignKey(User)
status_type = models.CharField(max_length=30, choices=STATUS_TYPES, default='online')
created_time = models.DateTimeField(auto_now_add=True)
finish_time = models.DateTimeField(blank=True, null=True)
time_diff = models.DateTimeField(blank=True, null=True)
I added time_diff to show the time difference between created_time and finish time. When I try an example in the shell, I use;
user_status.created_time
datetime.datetime(2016, 3, 31, 12, 50, 21, tzinfo=<UTC>)
user_status.finish_time
datetime.datetime(2016, 3, 31, 12, 51, 37, 998593, tzinfo=<UTC>)
user_status.finish_time - user_status.created_time
datetime.timedelta(0, 76, 998593)
Everything seems to be fine until now, however when I wrote user_status.save() it gave an error;
line 93, in parse_datetime
match = datetime_re.match(value)
TypeError: expected string or buffer
I did not understand why it gave such an error.
Thank you in advance.
Now you try to use DateTimeField, but this field can only be used for storing date and time (but not time difference). You should use DurationField for storing timedelta.
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()