0

I want a delta between two objects:

class Point(models.Model):

    measurement = models.ForeignKey(Measurement)
    time = models.DateTimeField()
    value = models.FloatField()

    def delta(self):
        measurement = self.measurement.point_set.order_by('time')
        measurement = measurement[-2]
        return self.value - measurement.value

But this obviously just works for the latest object. Is there a way to get the predecessors of the self.object in a time-wise sense?

Maximilian Kindshofer
  • 2,753
  • 3
  • 22
  • 37

1 Answers1

1
def delta(self):
    try:
        my_predecessor = self.objects\
            .filter(measurement_id=self.measurement_id, pk__lt=self.pk)\
            .order_by('pk')[-1]
    except IndexError:
        # there is no previous object
        return None
    else:
        return self.time - my_predecessor.time

self.measurement_id should be synonymous to self.measurement.pk

pk means primary key. The values are normally automatically assigned from a sequence.

pk__lt=self.pk means "objects whose pk is Less Than mine", or "created earlier than me". More here.

I order_by('pk'), so I ensure selecting Point objects in the order they were created (comparing integer fields is always faster than comparing DateTimeField objects. You can always replace it with order_by('time') if you will have some doubts :)

_id is described here. I used it to build a more optimal SQL query that only selects from one table (doesn't join the table of the Measurement model). The difference between _id and __id.

Finally, [-1] takes the last object. Django queryset slicing works very similar to python slicing.

Community
  • 1
  • 1
Art
  • 2,235
  • 18
  • 34