0

I am trying to run a query that gets me all the records from hour A to hour B (Example: all records saved within hour range of 23-00.)

I tried using date__range and ofcourse it did'nt help

here's the view

def issue_report(request, pk):
try:
    issue = Issue.objects.get(id = pk)
    start = issue.date_time
    end = issue.date_time + timedelta(minutes=30)


    if issue.merge == '2':
        pass
    else:
        
        issue = Issue.objects.filter(date__range = (start, end), customer = issue.customer.id, merge = '2').order_by('date_time').first()

            

    a = issue.date

    x = int(a.strftime('%Y'))
    y = int(a.strftime('%m'))
    z = int(a.strftime('%d'))

    hijri = Gregorian(x,y,z).to_hijri()

                         

    dbs = [Issue]
    transactions = sorted(
        [m
        for db in dbs
        for m in db.objects.filter(customer = issue.customer.id, date__range = (start, end), merge= '1', ).order_by('date_time')], 
        key=attrgetter('date_time')
    )

    for tx in transactions.copy():
        if tx.date_time < issue.date_time:
            transactions.remove(tx)

    transactions.insert(0, issue)

    return render(request, 'issue/report.html', context={'issue':issue, 'transactions':transactions ,'hijri':hijri})  
except AttributeError:
    return HttpResponse("<h1>Change Transaction type to ``Don't Merge``.</h1>")    

2 Answers2

1

To filter records based on a specific hour range, you can use the hour attribute of a date/time object and combine it with the gte and lt lookups. For example, to get all records from 11 PM to midnight, you can do:

from datetime import time

start_time = time(hour=23)
end_time = time(hour=0)

records = MyModel.objects.filter(
    my_datetime_field__time__gte=start_time, my_datetime_field__time__lt=end_time
)

This will give you all records where my_datetime_field has a time between 11 PM (23:00:00) and midnight (00:00:00). Note that we use lt for the end time because midnight is technically the start of a new day.

In your code, you can modify the transactions query to filter based on an hour range like this:

enter image description here

This will give you all transactions that occurred within 30 minutes after the issue data time. Note that I also simplified the list comprehension since it only contains one model class.

I hope this helps!

SamSparx
  • 4,629
  • 1
  • 4
  • 16
  • A question regarding this issue was last asked in 2015. I wasn't really expecting an answer. Anyways, Thank you very much man, you can't imagine how much I appreciate you answering. – pip install logic Jun 07 '23 at 00:00
  • does it take date into consideration? Like for example, tomorrow will it fetch today's data too that was recorded between 11 to midnight? Or will it only fetch that days data? – pip install logic Jun 07 '23 at 00:37
1

For simple ranges, Django filters can handle this natively. See the [docs for the hour and minute filters][1]

For 11pm to midnight you could simply use


    issue = Issue.objects.filter(
        #This will capture items in the same hour as the record
        date_time__hour = 23, 
        customer = issue.customer.id, 
        merge = '2'

    ##you could also refine to the first half hour using exclude.
    #).exclude(
    #    date_time__minute__gt=31
    ).order_by('date_time').first()

You can get the hour from an existing record fairly easily to use in your filter if required.

filter_hour = issue.date_time.hour
....
    issue = Issue.objects.filter(
        #This will capture items from 11pm to midnight
        date_time__hour = filter_hour, 

If you just want multiple hours you could use:


filter_hours = [21,22,23]

....
    issue = Issue.objects.filter(
        #This will capture items from 11pm to midnight
        date_time__hour__in = filter_hours, 

If you want to get a range based on a variable value from another item, for varying periods eg, the record time plus 130 mins, you might want to look into setting up a separate time field for that purpose, as described in [this answer][2]

An extra case based on comment - to limit this only to today

    #NB you may wish to run this for *yesterday* via timedelta 
    #if checking for 11pm - midnight, as day will be over at end of timeperiod
    t = timezone.localtime(timezone.now())
    
    issue = Issue.objects.filter(
        #This will capture items in a particular hour of a particular day
        date_time__hour = 23, 
        date_time__year = t.year,
        date_time__month = t.month,
        date_time__day = t.day, )

  [1]: https://docs.djangoproject.com/en/4.2/ref/models/querysets/#hour
  [2]: https://stackoverflow.com/questions/27845372/django-filter-datetime-field-by-time-irrespective-of-date
SamSparx
  • 4,629
  • 1
  • 4
  • 16