场景:车辆测试-(将车辆预订到测试单元中,然后进行测试)
出于示例目的,我创建了两个简化的模型:
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] 删除。
我来说两句