Given the following model (using django-simple-history
):
class MyModel (models.Model):
status = models.IntegerField()
history = HistoricalRecords()
I would like to get all instances that didn’t have a certain status
on a given date (i.e. all instances that had a different status on the limit date, plus all instances that didn’t exist at that time).
The following query will return all instances that never had status = 4
at any point before the limit date:
MyModel.filter (~Exists (
MyModel.history.filter (
id = OuterRef ("id"),
history_date__lte = limit_date,
status = 4))
But unfortunately it also removes instances that had status = 4
at some past date, then changed to a different status
by the limit date, and I want to keep those.
The following should give the correct result:
MyModel.filter (~Exists (
MyModel.history.filter (
id = OuterRef ("id"),
history_date__lte = limit_date)
.order_by ("-history_date")
[:1]
.filter (status = 4)))
Unfortunately it doesn’t work: Cannot filter a query once a slice has been taken.
This question links to this documentation page which explains that filtering is not allowed after the queryset has been sliced.
Note that the error comes from an assert
in Django. If I comment out the assert
in django/db/models/query.py:953
, then the code appears to work and gives the expected result. However commenting out an assert
in an upstream dependency is not a viable solution in production.
So is there a clean way to filter my queryset depending on some past state of the object?