I’ve got a field in one model like:
class Sample(models.Model):
date = fields.DateField(auto_now=False)
Now, I need to filter the objects by a date range.
How do I filter all the objects that have a date between 1-Jan-2011 and 31-Jan-2011?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Use
Sample.objects.filter(date__range=["2011-01-01", "2011-01-31"])
Or if you are just trying to filter month wise:
Sample.objects.filter(date__year='2011',
date__month='01')
Edit
As Bernhard Vallant said, if you want a queryset which excludes the specified range ends you should consider his solution, which utilizes gt/lt (greater-than/less-than).
Method 2
You can use django’s filter with datetime.date objects:
import datetime
samples = Sample.objects.filter(sampledate__gte=datetime.date(2011, 1, 1),
sampledate__lte=datetime.date(2011, 1, 31))
Method 3
When doing django ranges with a filter make sure you know the difference between using a date object vs a datetime object. __range is inclusive on dates but if you use a datetime object for the end date it will not include the entries for that day if the time is not set.
from datetime import date, timedelta startdate = date.today() enddate = startdate + timedelta(days=6) Sample.objects.filter(date__range=[startdate, enddate])
returns all entries from startdate to enddate including entries on those dates. Bad example since this is returning entries a week into the future, but you get the drift.
from datetime import datetime, timedelta startdate = datetime.today() enddate = startdate + timedelta(days=6) Sample.objects.filter(date__range=[startdate, enddate])
will be missing 24 hours worth of entries depending on what the time for the date fields is set to.
Method 4
You can get around the “impedance mismatch” caused by the lack of precision in the DateTimeField/date object comparison — that can occur if using range — by using a datetime.timedelta to add a day to last date in the range. This works like:
start = date(2012, 12, 11) end = date(2012, 12, 18) new_end = end + datetime.timedelta(days=1) ExampleModel.objects.filter(some_datetime_field__range=[start, new_end])
As discussed previously, without doing something like this, records are ignored on the last day.
Edited to avoid the use of datetime.combine — seems more logical to stick with date instances when comparing against a DateTimeField, instead of messing about with throwaway (and confusing) datetime objects. See further explanation in comments below.
Method 5
you can use “__range”
for example :
from datetime import datetime start_date=datetime(2009, 12, 30) end_date=datetime(2020,12,30) Sample.objects.filter(date__range=[start_date,end_date])
Method 6
To make it more flexible, you can design a FilterBackend as below:
class AnalyticsFilterBackend(generic_filters.BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
predicate = request.query_params # or request.data for POST
if predicate.get('from_date', None) is not None and predicate.get('to_date', None) is not None:
queryset = queryset.filter(your_date__range=(predicate['from_date'], predicate['to_date']))
if predicate.get('from_date', None) is not None and predicate.get('to_date', None) is None:
queryset = queryset.filter(your_date__gte=predicate['from_date'])
if predicate.get('to_date', None) is not None and predicate.get('from_date', None) is None:
queryset = queryset.filter(your_date__lte=predicate['to_date'])
return queryset
Method 7
Is simple,
YourModel.objects.filter(YOUR_DATE_FIELD__date=timezone.now())
Works for me
Method 8
Model
date = models.DateField()
View
def get_queryset(self):
fromDate = self.request.query_params.get('fromDate',None)
toDate = self.request.query_params.get('toDate',None)
response = yourModel.objects.filter(date__gte=fromDate,date__lte=toDate)
return response
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0