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

后端 未结 7 1956
野趣味
野趣味 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: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")
        )]
    )
    

提交回复
热议问题