0

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?

adonayE
  • 1
  • 1

0 Answers0