I have a slow-running Django ListView on a complaints management app I wrote. It's running slow because, when using the ORM, it doesn't hit the database very efficiently.
I've written the following query, which gets the information I need efficiently:
WITH triages AS (
SELECT
agreed_resolution_date
, complaint_id
, date_completed
, id
, stage_id
, MAX(id) OVER(PARTITION BY complaint_id, stage_id) AS ltst
FROM complaints_triage
)
SELECT
cpt.id
, cplnt.first_name || ' ' || cplnt.last_name AS complainant
, DATE_PART('year', cs.date_case_received) AS case_year
, cs.case_reference AS case_reference
, CASE WHEN cpt.handler_id IS NULL
THEN NULL
ELSE usr.first_name || ' ' || usr.last_name
END AS complaint_handler
, tm.name AS team
, stg.stage AS complaint_stage
, CASE WHEN trg.agreed_resolution_date IS NULL
THEN ((cpt.date_received + integer '5') - CURRENT_DATE)
ELSE (trg.agreed_resolution_date - CURRENT_DATE)
END AS time_left
FROM complaints_complaint AS cpt
INNER JOIN complaints_complainant AS cplnt
ON cpt.complainant_id = cplnt.id
LEFT JOIN complaints_case AS cs
ON cpt.case_id = cs.id
LEFT JOIN auth_user AS usr
ON cpt.handler_id = usr.id
INNER JOIN complaints_stage AS stg
ON cpt.stage_id = stg.id
INNER JOIN community_team AS tm
ON cpt.team_id = tm.id
LEFT JOIN triages AS trg
ON trg.stage_id = cpt.stage_id
AND trg.complaint_id = cpt.id
AND trg.id = trg.ltst
WHERE cpt.date_closed IS NULL
ORDER BY time_left
I would like to use this query to override get_queryset in the ListView and use the results as a queryset, with the column headings as the attribute names. But using this query to return results as described in the docs returns a list (using cursor.fetchall) rather than a queryset. Is there any way to return a queryset from this kind of SQL query? Alternatively, is there another established way to do what I'm trying to?
TemplateViewand adding the list of tuples from the query as context the best way to go about this?