Django __date not working with date() or string - django

I have the following model field:
inbound_date = models.DateTimeField()
I want to filter on date, and not care about the time.
I have inserted two test objects which return the following values for inbound_date:
2018-11-14 00:00:00+00:00
2018-11-15 08:37:09+00:00
But all my attempts at retrieving the objects fail:
AppInbound.objects.filter(inbound_date__date=datetime.date(2018, 11, 15))
Or
AppInbound.objects.filter(inbound_date__date='2018-11-15')
But all seem to return an empty QuerySet.
The only one I did manage to get working was:
AppInbound.objects.filter(inbound_date__startswith='2018-11-15')
Which returns the the last objects, with datetime of 2018-11-15 08:37:09+00:00.
Can someone explain what is going wrong here?
It is an MySQL database, and we have TZ enabled.

You can try like this:
AppInbound.objects.filter(inbound_date__lt=datetime.date(2018, 11, 15), inbound_date__gte=datetime.date(2018, 11, 14)) # will return objects for 14th November.
Or you can check this answer on how to filter on specific dates.
If you are only concerned with using date then DateField should be used here:
inbound_date = models.DateField()
Then you should be able to filter with date object(datetime.date).

Related

Django: Filter for month with timezone (after switching from SQLite to PostgreSQL)

In preparation for deployment, I switched from SQLite to PostgreSQL (following this advice). Now I have some trouble filtering certain items for timestamp by month which I didn't have before with SQLite. The problem is, that I get the items of the previous month instead of the current one. Look, this is what my code basically looks like:
models.py
class Dummy(models.Model):
…
timestamp = models.DateTimeField()
…
views.py
…
current = datetime.date.today().replace(day=1)
dummies = Dummy.objects.values(month=TruncMonth('timestamp')).
filter(month__year=current.year).
filter(month__month=current.month)
…
I actually have several Dummy entries for the current month (which is 10), but dummies remain empty. If I replace current.month with 9, I get exact these entries. Like I said before, this is only the case with PostgreSQL. As long as I used SQLite, everything was OK.
After some research I understand where the problem apparently comes from: there seems to be a difference how these different types of databases handle the timezones, see e.g. this answer.
The timestamp of the Dummy entries is stored as UTC in the database itself. If I look at one item of dummies (which I get with 9 as mentioned above), it has month values like that:
datetime.datetime(2020, 10, 1, 0, 0, tzinfo=<DstTzInfo 'Europe/Berlin' CEST+2:00:00 DST>)
The value of current is datetime.date(2020, 10, 1), without any timezone information. So I assume the month value of dummies using PostgreSQL is somehow converted to UTC and the date changes do someting like 2020, 9, 30.
I tried a lot, but I still do not know how to solve this problem, even though it must be quite easy, I guess. Any help is appreciated.
I was on the right track and found the answer to my question by myself. This code works:
views.py
from django.utils import timezone
…
current = timezone.now().replace(day=1, hour=0, minute=0, second=0, microsecond=0)
dummies = Dummy.objects.values(month=TruncMonth('timestamp')).
filter(month=current)
Now current is no longer date but datetime including a timezone and therefore fits perfectly to month as a filter.

Django filter by datetime month__gte is not working

I'm using Django 2.2
I have a created field of DateTime type.
I'm using following command to filter the records which are greater than specific date
q.filter(created__year__gte=2020, created__month__gte=3, created__day__gte=1)
In my database there are records for March (3) month and more but not for February (2).
When above command is executed, it gives me queryset list of data greater than March 1. But when I use the following command
q.filter(created__year__gte=2020, created__month__gte=2, created__day__gte=28)
Where month is February (2), it is not giving any data and the queryset is blank.
Using datetime object gives error
received a naive datetime (2020-03-01 00:00:00) while time zone support is active
Why filter is not working with gte even when month is less than 3?
Why do you want to filter like this? In your case it is totally unnecessary. Just filter by date strictrly
q.filter(created__gte=datetime.datetime(2020, 3, 1))
Use:
q.filter(created__date__gte=datetime.date(2020, 3, 1))
Regarding the filter, its working perfectly when month < 3, but if you specify that day > 28, then its already narrowing results set to only data that was crated between 29-31 day for every month, not only Feb. And most likely its not what you want.
The error was not with the Django setup, instead it was with the MySQL configuration due to missing timezone data.
Check this answer for how to resolve this error
https://stackoverflow.com/a/60844090/3719167

How to properly use dates in object filters

I'm using Django ORM to access database models, it works well when I use objects.all(), it returns all the objects in the database. But when I want to filter on a date I add a filter using the new date type it doesnt return anything, I get a blank QuerySet. After searching and trying different things for many hours I discovered object.filter(date__gte=date) works.
For example:
This works, I get all the records where date = today:
today = date.today()
Model.objects.filter(date__gte=today)
These do not work, they return empty QuerySets:
Model.objects.filter(date__contains=today)
Model.objects.filter(date__startswith=today)
Model.objects.filter(date__date=date.today())
My question is what am I doing wrong that one type of query works but not the other, when they should all return the same data?
You can do it like this(Reference) for DateTimeField:
Model.objects.filter(date__date=datetime.today())
If its a DateField, then simply do:
Model.objects.filter(date=datetime.today())

filtering DateField on the basis of substring in django

So I am using a DateField for displaying the date. Which when passed to a template using contexts, renders in the format Nov. 4, 2018
Now there are multiple entries of such dates in the database. And I want to filter on the basis of string of the date actually shown. i.e when I type in Nov 4, or nov 4 or NOV 4 in my search input field, it should show the matched result. More like a substring match.
Now the only problem is that i do not know how to convert my_model.date field in to Nov. 4, 2018.
str(my_model.date) returns 2016-11-04 and I do not want to parse this with month_number-to-month_name map
I think, any of the two solutions should work.
1) Django filters that allow me to do so.
2) converting my_model.date into Nov. 4, 2018 string
Help please, been stuck on this forever now
Because you specifically mention rendering the date in a template, I'm not sure if the search operation you're referring to is a front-end, user-facing thing or a backend database query.
If you want to convert my_model.date to a prettier string before sending it to the template before display, you can process it in your view with strptime - this will give you the control that you're missing with the str wrapper: https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior While there are template tags that can do this for you as well, doing it in your view is faster and better.
If this is a DB query, then remember that you can filter date objects by their attributes. For example, to get all instances created on November 11th, 2011:
MyModel.objects.filter(
date__day = 11,
date__month = 11,
date__year = 2018
)
Note the double underscores.
Responding to your comment, now that I better understand your goal:
Date fields do not store their more "verbose" date information in a queryable spot. If you want to be able to query for things like "Nov" instead of 11 then you'll need to add another attribute (or attributes) to your model to propagate that computed data into queryable containers.
If it were me, I would do this within my_model:
from datetime import date
...
rawDate = models.DateField(...) #your current date field
formatted_month = models.CharField(...)
formatted_day = models.IntegerField(...)
formatted_year = models.IntegerField(...)
...
def save(self):
self.formatted_month = date.strftime(self.rawDate, '%b')
self.formatted_day = date.strftime(self.rawDate, '%d')
self.formatted_year = date.strftime(self.rawDate, '%Y')
super().save()
Now you can perform your NOV/nov/Nov lookup like so:
MyModel.objects.filter(
formatted_month__iexact = 'Nov'
)
This still requires you to split the month and day in your search term before hitting the database. If you wanted to squash these down a bit, you could instead store all of the formatted date info in a single field:
formatted_date = models.CharField(...)
...
def save(self):
self.formatted_date = date.strftime(self.rawDate, '%b %d %Y')
Then if your query looks like "NOV 4", you could do:
MyModel.objects.filter(formatted_date__icontains='NOV 4')

How do I compare DateTime objects to UNIX timestamps when filtering results in django?

I am using the FullCalendar plugin for JQuery.
This plugin passes a unix timestamp to a url (both start and end times), which is then used to query the event objects in the database and pull out events which fall within the range of start-end.
However, I keep getting a validation error because the times in my database are stored as datetimes and the value I am comparing them to is a UNIX timestamp.
How can I compare these two dates when running a query?
def fetch_events(request):
start = request.GET.get('start')
end = request.GET.get('end')
e = Event.objects.filter(start__gte=start, end__lte=end).values('id','title','start','end')
data = simplejson.dumps(list(e), cls=DjangoJSONEncoder)
return HttpResponse(data)
Try making a datetime object from a timestamp by using the datetime.datetime.fromtimestamp function. Here's a quick demonstration:
In [7]: import datetime
In [8]: datetime.datetime.fromtimestamp(2344353453)
Out[8]: datetime.datetime(2044, 4, 15, 19, 17, 33)