I have a model called Loans
, containing (among others) the following fields: LibAccountId
, Title
, StartDate
, EndDate
and RemoteId
.
So, some records could look like this:
LibAccountId,Title,StartDate,EndDate,RemoteId
1, Book title A, 2021-01-01, 2021-02-05, 1234
1, Book title A, 2021-01-01, 2021-01-21, 1234
1, Book title A, 2021-01-01, 2021-01-14, 1234
5, Book title B, 2021-05-05, 2021-06-01, 5678
I want to make a ModelManager that returns a queryset, where for a unique record (based on LibAccountId
, Title
, StartDate
and - if present - RemoteId
), only the ones with the most recent Enddate
are returned.
So, this would return:
1, Book title A, 2021-01-01, 2021-02-05, 1234 # 2021-02-05 is most recent
5, Book title B, 2021-05-05, 2021-06-01, 5678
Iāve managed to write native python code to filter this (returning a list of Loan objects), and (my SQL is a bit rusty) a raw SQL query, also returning the desired result.
However, with both approaches, it doesnāt give me a Queryset that I can further apply Django ORM methods like filter()
, etc.
So, how can I write the following raw SQL query with Djangoās native querylanguage?
class UniqueLoansManager(models.Manager):
"""Make loans that have been extended, distinct to
one single loan (the last one)
"""
def get_queryset(self):
return super().get_queryset().raw("""
SELECT *
FROM Loans
INNER JOIN (
SELECT LibAccountId as LAI, Title AS T,StartDate as SD, RemoteId AS RI, MAX(EndDate) AS max_enddate
From Loans
GROUP BY LibAccountId, Title, StartDate, RemoteId
) last_by_enddate ON
Loans.LibAccountId = LAI
AND Loans.Title = T
AND Loans.StartDate = SD
AND (Loans.RemoteId= RI OR (Loans.RemoteId IS NULL AND RI IS NULL))
AND Loans.EndDate = last_by_enddate.max_enddate
ORDER BY Loans.EndDate DESC
"""
)
# Problem: return value is a RawQuerySet