【发布时间】:2020-05-24 00:05:13
【问题描述】:
一些背景
我正在考虑使用 Django 重建现有的 Laravel 网站。这是一个允许共享来自无人机/无人机推进组件的基准数据的网站。一些基准测试是在同时测试多个电机和螺旋桨时完成的,这意味着一个电池将承受多个电机的负载,但这也意味着来自一个螺旋桨的气流会影响另一个螺旋桨上捕获的数据。这意味着数据是物理耦合的。 Here is an example。现在我正在尝试构建这个项目以允许即将推出的功能,并查看 Django ORM 是否适合。
简化的 Django 模型
class Benchmark(models.Model):
title = models.CharField()
private = models.BooleanField(default=False)
hide_torque = models.BooleanField(default=False)
class AbstractComponent(models.Model):
brand = models.CharField()
name = models.CharField()
class Meta:
abstract = True
class Motor(AbstractComponent):
shaft_diameter_mm = models.FloatField()
class Propeller(AbstractComponent):
diameter_in = models.FloatField()
class Battery(AbstractComponent):
capacity_kwh = models.FloatField()
class Powertrain(models.Model):
benchmark = models.ForeignKey(Benchmark, on_delete=models.CASCADE, related_name='powertrains')
motor = models.ForeignKey(Motor, on_delete=models.CASCADE)
propeller = models.ForeignKey(Propeller, on_delete=models.CASCADE, blank=True, null=True)
battery = models.ForeignKey(Battery, on_delete=models.CASCADE, blank=True, null=True)
class DerivedDataManager(models.Manager):
def get_queryset(self):
return super().get_queryset()\
.annotate(electrical_power_w=F('voltage_v') * F('current_a'))\
.annotate(mechanical_power_w=F('torque_nm') * F('rotation_speed_rad_per_s'))\
.annotate(motor_efficiency=F('mechanical_power_w') / F('electrical_power_w'))
class DataSample(models.Model):
powertrain = models.ForeignKey(Powertrain, on_delete=models.CASCADE, related_name='data')
time_s = models.FloatField()
voltage_v = models.FloatField(blank=True, null=True)
current_a = models.FloatField(blank=True, null=True)
rotation_speed_rad_per_s = models.FloatField(blank=True, null=True)
torque_nm = models.FloatField(blank=True, null=True)
thrust_n = models.FloatField(blank=True, null=True)
objects = models.Manager()
derived = DerivedDataManager()
class Meta:
constraints = [
models.UniqueConstraint(fields=['powertrain', 'time_s'], name='unique temporal sample')
]
问题
我能够将“派生”测量值(如electrical_power_w)添加到数据的每一行,但我不知道如何添加将多个传动系统的数据组合到同一基准测试中的派生测量值:
假设 3 个动力系统,每个都有自己的电压和电流数据,我该怎么做:
总功率 = powertrain1.power + powertrain2.power + powertrain3.power
对于每个单独的时间戳 (time_s)?仅当对同时采集的样本求和时,总功率才有意义。
目标
在不加载 Django 中的所有数据库数据的情况下,考虑到一些业务逻辑,我最终希望获得最大总功率方面的 5 个顶级基准:
- 标记为私有的基准会被自动排除(直到授权进入)
- 选择隐藏扭矩的基准会自动生成扭矩数据,同时所有派生的机械功率和电机效率值都变为无。
我想重新创建this table,但附加了额外的列,例如“最大推力”等...此表是从数据库本身内部分页的。
【问题讨论】:
标签: django django-models django-orm django-aggregation django-annotate