How do I filter query objects by date range in Django?

后端 未结 7 1521
执念已碎
执念已碎 2020-11-22 16:02

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 obje

相关标签:
7条回答
  • 2020-11-22 16:26

    Still relevant today. You can also do:

    import dateutil
    import pytz
    
    date = dateutil.parser.parse('02/11/2019').replace(tzinfo=pytz.UTC)
    
    0 讨论(0)
  • 2020-11-22 16:27

    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))
    
    0 讨论(0)
  • 2020-11-22 16:31

    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).

    0 讨论(0)
  • 2020-11-22 16:33

    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.

        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.

        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.

    0 讨论(0)
  • 2020-11-22 16:38

    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.

    0 讨论(0)
  • 2020-11-22 16:38

    Is simple,

    YourModel.objects.filter(YOUR_DATE_FIELD__date=timezone.now())
    

    Works for me

    0 讨论(0)
提交回复
热议问题