Hi,
I would like your advice on how to link the data models I need. I’m developing a web application to manage equipment. The equipment can be metrology instruments, scales and sensors. I’ve made an Equipment model with fields that are generic to the other models, so I’m inheriting the Equipment class from the other models Instrument, Balance and Sensor, as I’d like the Ids to follow each other and have shared fields. The reflection was that everything is Equipment, so an Equipment can contain 0 or several Equipments, an Instrument can contain 0 or several Sensors, a Sensor can be contained in only one Equipment, a Balance can have 0 or several Sensors. What I did:
class Equipment(TrackableMixin, PurchaseInformation):
old_name = models.CharField(max_length=50, blank=True, verbose_name="ancien nom")
name = models.CharField(max_length=50, blank=True, verbose_name="nom")
type = models.CharField(
max_length=50, choices=EquipmentTypeChoice.choices, default=EquipmentTypeChoice.INSTRUMENT, verbose_name="type"
)
status = models.CharField(
max_length=50, choices=PhysicalStatusChoices.choices, default=PhysicalStatusChoices.OK, verbose_name="état"
)
container = models.ForeignKey(
"self",
related_name="container_equipement",
on_delete=models.RESTRICT,
null=True,
blank=True,
verbose_name="conteneur",
)
information_checked = models.BooleanField(default=False, verbose_name="informations vérifiées")
def __str__(self):
return self.name + " (" + self.old_name + ")"
class Meta:
db_table = "mm_equipments"
class InstrumentManager(models.Manager):
def get_sensors(self):
sensors = Sensor.objects.filter(container_id=self.id)
return sensors
class Instrument(Equipment):
objects = InstrumentManager()
class Meta:
db_table = "mm_instruments"
def __str__(self):
return self.name + " (" + self.old_name + ")"
class Sensor(Equipment, OriginalRange):
physical_quantity = models.ForeignKey(
PhysicalQuantity, on_delete=models.RESTRICT, related_name="sensors", verbose_name="grandeur physique"
)
is_standard = models.BooleanField(default=False, verbose_name="étalon ?")
resolution = models.FloatField(null=True, blank=True, verbose_name="résolution")
objects = SensorManager()
class Meta:
db_table = "mm_sensors"
def name(self):
match self.physical_quantity.slug:
case "temperature":
return "T" + str(self.id).zfill(4)
case "flowrate":
return "Q" + str(self.id).zfill(4)
case "pressure":
return "P" + str(self.id).zfill(4)
case "length":
return "L" + str(self.id).zfill(4)
case _:
return "S" + str(self.id).zfill(4)
def __str__(self):
old_name = ""
if self.old_name:
old_name = f" ({self.old_name})"
return self.name() + old_name
With this system, when I want to retrieve the sensors of an instrument, I have to make an InstrumentManager, which is higher up. I can’t directly make the request instrument.sensors.all(). So I’m wondering whether this is a good solution, or whether I should put an FK equipment in the Sensor model that would allow me to access the inverted relationship directly. What do you think of this solution? Is it viable and scalable?
Thank you.