简体   繁体   中英

django queryset cannot run function inside annotate and Sum

I have two queryset and I want to do Addition from those two queryset but one query value are Int type (eg 1.5, 2.75 ) but others have time like string (eg 12:20:59). I need to convert that string to Int type so I can do use Sum Function in Annotate.

First queryset

timesheet_total_by_project = TimesheetEntry.objects.filter(
    created_by_id=current_user,
    timesheet__for_date__gte=start_tim,
    timesheet__for_date__lte=end_date,
    project__is_visible=True
).values(
    'project__name', 'project__id'
).distinct().annotate(totalsum=Sum('minutes', output_field=FloatField()) / 60.0)

2nd Queryset

ticket_total_time = Ticket.objects.filter(
     assigned_to=user, total_time__isnull=False, project__is_visible=True
).values(
    'title','project__id'
).distinct().annotate(totalsum=Sum('total_time', output_field=FloatField()) / 60.0)

I have tried

def get_sec(time_str):
        print("string",time_str)
        """Get Seconds from time."""
        h, m, s = time_str.split(':')
        return int(h) * 3600 + int(m) * 60 + int(s)
ticket_total_time = Ticket.objects.filter(assigned_to=user,total_time__isnull=False,project__is_visible=True).values('title','project__id').distinct().annotate(totalsum=Sum(get_sec('total_time'), output_field=FloatField()) / 3600.0)

Expected Output is would be 12.5 but output for print("string",time_str)

string total_time

Also says

ValueError: not enough values to unpack (expected 3, got 1)
def get_sec(time_str):
    print(f'{time_str = }')
    """Get Seconds from time."""
    if not time_str:
        return 0
    h, m, s = time_str.split(':')
    return int(h) * 3600 + int(m) * 60 + int(s)

MySQL has a STR_TO_DATE function that will convert a string to a date. You can run arbitrary database functions with a Func expression :

from django.db.models import F, Func, Value

ticket_total_time = Ticket.objects.filter(
     assigned_to=user, total_time__isnull=False, project__is_visible=True
).values(
    'title','project__id'
).distinct().
annotate(time_t=Func(F('total_time'), Value('%H:%i:%s'), function='STR_TO_DATE')).
annotate(totalsum=Sum('time_t', output_field=FloatField()) / 60.0)

I tried this solution and it work fine. Now Time_to_sec function is working inside annotate.

from django.db.models import F, Func

class Time_to_sec(Func):
           function = 'TIME_TO_SEC'
           lookup_name = 'sec'

ticket_total_time = Ticket.objects.filter(assigned_to=user,total_time__isnull=False,project__is_visible=True).values('project__id').distinct().annotate(totalsum=Sum(Time_to_sec('total_time', output_field=FloatField()) / 3600.0))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM