Django:ORM设计问题

刘易斯

场景:车辆测试-(将车辆预订到测试单元中,然后进行测试)

出于示例目的,我创建了两个简化的模型:

class Vehicle(models.Model):
    registration = models.CharField(unique=True, max_length=10)
    tyre_pressure = models.IntegerField()

class Booking(models.Model):
    STATUS_CHOICES= (('Booked','Booked'),('Complete','Complete'))

    booking_datetime = models.DatetimeField(auto_now=True)
    vehicle = models.ForeignKey(Vehicle, on_delete=SET_NULL)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES)

创建/预订预订后,它将创建Booking状态为已预订对象,并且预订已分配了车辆。

测试完成后,Booking对象将其状态更改为Complete车辆现在空置用于下一次测试。

问题

tyre_pressure用于车辆(例如)可在后的预订完成以后改变(可能为不同的测试)并导致测试有不正确的数据,该特定时间。

我希望预订记录能够反映预订的特定时间的车辆状态,而不是当前值。

我考虑过的

  • 修改/更新车辆后,它会创建一个新的唯一ID。这将与字段中unique=True参数冲突registration

  • Booking模型内包括给定测试的所有车辆字段,而不是Vehicle对象。

  • 可能创建一个新VehicleConfiguration模型。包含除唯一键之外的所有属性。每次更改车辆都会创建新记录,并且历史更改会随更改日期一起存储。像这样:

class Vehicle(models.Model):
    registration = models.CharField(unique=True, max_length=10)
    vehicle_config = models.ForeignKey(VehicleConfiguration, on_delete=models.CASCADE) 

class VehicleConfig(models.Model):
    tyre_pressure = models.IntegerField()
    [...]
梅尔文

这是一种非常常见的模式,在这种模式下,您需要在某个时间点冻结​​模型的冻结状态。有多种处理方法。在电子商务中,当您购买目录中的产品时,您会看到这种模式,它不能是订单中的外键,但是需要以当时的价格(甚至是当时的名称)进行复制。订单引用PurchasedItem而不是Product,并且它们共享许多字段。

但是,在这种情况下,您可以将测试数据与车辆分开:

class Booking(models.Model):
     vehicle = models.ForeignKey(Vehicle, related_name='bookings')
     test_results = models.ForeignKey('Test', null=True)  # ManyToMany if one booking can result in multiple tests
     ... financial data

class Vehicle(models.Model):
     ... static vehicle data, like make, license plate, owner, etc

class Test(models.Model):
    test_time = models.DateTimeField(auto_now_add=True)
    tyre_pressure = models.IntegerField()

因此,在这种情况下,预订会将车辆和测试捆绑在一起,并且假定测试为静态。车辆的胎压将是最新测试的替代方法:

class Vehicle(models.Model):
    ...
    @property
    def tyre_pressure(self) -> int:
        return self.bookings.filter(
            status='completed', test__isnull=False
        ).latest('test__test_time').tyre_pressure

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章