How do I filter by time in a date time field?

后端 未结 7 1957
野趣味
野趣味 2021-01-18 03:49

In the model \'entered\' is a datetime field. I want to query the data to find all entry\'s that where made between noon(start_time) and 5:00pm (end_time).

s         


        
相关标签:
7条回答
  • 2021-01-18 04:29

    You can use range to filter in between. I found this the best way to filter since SQL does filtering better than Django.

    fromRange=datetime.datetime.strptime(request.GET.get('from'),'%Y-%m-%dT%H:%M:%S.%fZ')
    toRange=datetime.datetime.strptime(request.GET.get('to'),'%Y-%m-%dT%H:%M:%S.%fZ')
    
    entry = Entry.objects.filter(entryTime__range=(fromRange,toRange))
    
    0 讨论(0)
  • 2021-01-18 04:37

    I suggest filter x<=arg and exclude x>=arg2.

    0 讨论(0)
  • 2021-01-18 04:42

    I don't believe there's built-in support for this, but you can pass extra where-clause parameters (warning: some possibility of introducing DB-dependent behaviour here).

    For example, on Postgres, something like:

    Entry.objects.extra(where=['EXTRACT(hour from entered) >= 12 and '\
                        'EXTRACT(hour from entered) < 17'])
    

    If you're using potentially unsafe input to determine the values 12 and 17, note that you can also specify a params option to extra that will ensure proper quoting and escaping, and then use the standard sql %s placeholders in your where statement.

    0 讨论(0)
  • 2021-01-18 04:46

    Using SQLite as an example, a relatively clean and generic solution would be:

    Entry.objects.extra(where=["time(entered) between '%s' and '%s'"],
                        params=[start_time.strftime("%H:%M"), end_time.strftime("%H:%M")])
    
    0 讨论(0)
  • 2021-01-18 04:48

    I just figured out a solution for a similar use case – perhaps someone finds this useful:

    In my case, I have Availability and Constraint models like so (simplified):

    class Availability(...):
        start = models.DateTimeField()
        end = models.DateTimeField()
    
    class Constraint(...):
        from = models.TimeField()
        to = models.TimeField()
    

    I wanted to find availabilities that don't violate any constraints.

    With Postgres, this worked for me:

    Availability.objects.extra(
        where=['NOT (start::time, "end"::time) OVERLAPS (\'{0}\'::time, \'{1}\'::time)'.format(
            from.strftime("%H:%M"), to.strftime("%H:%M")
        )]
    )
    

    Note how you can cast DateTime to Time (or rather timestamp to time without timezone in Postgres terms) with ::time and then use OVERLAPS to compare the time ranges.

    And in regards to the original question, you can also do:

    Availability.objects.extra(
        where=['start::time BETWEEN \'{0}\'::time AND \'{1}\'::time AND
                "end"::time BETWEEN \'{0}\'::time AND \'{1}\'::time'.format(
            from.strftime("%H:%M"), to.strftime("%H:%M")
        )]
    )
    
    0 讨论(0)
  • 2021-01-18 04:50

    You could filter in python instead using the db's mechanisms:

    for e in Entry.objects.all():
       if i.entered.hour>= 9 and i.entered.hour < 17 :# or break down to minutes/seconds
            list.append(e)
    

    but both solutions are ugly, i think.

    Steve, you have to decide, what is less ugly for you:

    • processsing a lot of data in a for-loop,
    • or use .extra(..) and by-passing the orm-system
    0 讨论(0)
提交回复
热议问题