Mario Signorino
Mario Signorino

Reputation: 123

How to get another related result in a django model

Let's say I have this model in django:

class DeviceSensorChange(models.Model):
    device = models.ForeignKey(Device, on_delete=models.CASCADE, db_index=True)
    sensor = models.ForeignKey(DeviceDigitalSensor, on_delete=models.CASCADE, db_index=True, related_name='sensorchanges')
    time = models.DateTimeField(auto_now_add=True)
    value = models.BooleanField(default=False)

it describes how and when some "sensors" changes in time (a history of binary buttons: on and off). Then there is a ListView filtered by device or by sensor or by time.

I want to add another column in the view, that shows the elapsed time since the last change of the same sensor in the same device: it means I should to go back in the table looking for the same device, same sensor, get the time and make the subtraction.

Where is the right place to do that? I must not change the model and the information is needed just in the view to help the user, no need to store it.

Is it possbile to add a elapsed() function in the model? Or this is something that has to be done in the template? Or in the ListView itself?

Upvotes: 0

Views: 31

Answers (1)

Abdul Aziz Barkat
Abdul Aziz Barkat

Reputation: 21797

You can simply add a method / property to your model to do this. To get the previous object you can simply use get_previous_by_FOO [Django docs]:

class DeviceSensorChange(models.Model):
    device = models.ForeignKey(Device, on_delete=models.CASCADE, db_index=True)
    sensor = models.ForeignKey(DeviceDigitalSensor, on_delete=models.CASCADE, db_index=True, related_name='sensorchanges')
    time = models.DateTimeField(auto_now_add=True)
    value = models.BooleanField(default=False)
    
    def get_elapsed_time(self):
        try:
            prev = self.get_previous_by_time(device=self.device, sensor=self.sensor)
            return self.time - prev.time # Will return time delta
        except DeviceSensorChange.DoesNotExist:
            return "First change"

In the template you can simply write:

{{ device_sensor_change_instance.get_elapsed_time }}

Upvotes: 1

Related Questions