I have the following situation:
I am creating an app where I have a Person
model and I want to store a status history in a table, so that looking for the most recent status in the table would return the current status of the person.
My solution was creating a Status
table with a Foreign Key pointing to the Person
. Looking for the most recent entry in person.status_set
would make it easy looking for the current status.
class Person(models.Model):
...
def _get_status(self):
return self.status_set.order_by("-timestamp").first()
@property
def status(self):
try:
return self._get_purchase_status().status
except AttributeError:
# TODO: log error: Person without status.
return None # TODO: Change this.
@status.setter
def status(self, new_status):
s = Status(
person=self,
status=new_status
)
s.save()
@status.deleter
def status(self):
if self.status:
self.status_set.order_by("-timestamp").first().delete()
class Status(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
status = models.CharField(
max_length=50,
)
timestamp = models.DateTimeField(auto_now_add=True)
When I try to create a QuerySet containing the person and the last status info, I perform this query:
Person.objects.annotate(
person_status=Subquery(
Status.objects.filter(person_id=OuterRef("id")).order_by("-timestamp").values("status")[:1]
)
).values()
Calling the annotate
function using .values()
at the end works as expected, but when I only run the annotate
function,
Person.objects.annotate(
person_status=Subquery(
Status.objects.filter(person_id=OuterRef("id")).order_by("-timestamp").values("status")[:1]
)
)
I see that there are instances created in the Status
table for each Person
(said in other words, there is a new instance of Status
added to the status_set
of each Person
instance).
I do not think that this behaviour is expected. Could someone confirm or maybe explain, why does it happen?