django - Django ORM 中的动态视图 - 最佳方法?
问题描述
一些背景
我正在考虑使用 Django 重建现有的 Laravel 网站。这是一个允许共享来自无人机/无人机推进组件的基准数据的网站。一些基准测试是在同时测试多个电机和螺旋桨时完成的,这意味着一个电池将承受多个电机的负载,但这也意味着来自一个螺旋桨的气流会影响另一个螺旋桨上捕获的数据。这意味着数据是物理耦合的。这是一个例子。现在我正在尝试构建这个项目以允许即将推出的功能,并查看 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 个动力系统,每个都有自己的电压和电流数据,我该怎么做:
Total_power = powertrain1.power + powertrain2.power + powertrain3.power
对于每个单独的时间戳(time_s)?仅当对同时采集的样本进行求和时,总功率才有意义。
目标
在不加载 Django 中的所有数据库数据的情况下,考虑到一些业务逻辑,我最终希望获得最大总功率方面的 5 个顶级基准:
- 自动排除标记为私有的基准(直到 auth 出现)
- 选择隐藏扭矩的基准自动生成扭矩数据,同时所有派生的机械功率和电机效率值都变为无。
我想重新创建此表,但附加了额外的列,例如“最大推力”等...该表是从数据库本身内部分页的。
解决方案
嗯,这是一个相当棘手的导航。我将首先添加以下注释模型方法:
from django.db.models import Sum
我想那将是添加的情况:
.annotate(total_power=Sum(electrical_power_w))
但我认为问题在于您的每一行都DerivedDataManager
queryset
代表一个,而该行又通过该字段DataSample
链接到一个。Powertrain
ForeignKey
最好在业务逻辑层执行此操作,按动力总成的 UUID 分组(您需要将其添加到Powertrain
模型中 - 请参阅https://docs.djangoproject.com/en/3.0/ref/models/fields/# uuidfield了解如何使用它的详细信息。然后,因为您已分组,您可以将Sum
注释应用于queryset
.
所以,我认为你想沿着这条路导航:
DataSample.objects.order_by(
'powertrain'
).aggregate(
total_price=Sum('electrical_power_w')
)
推荐阅读
- google-app-engine - 语义中的 YAML 错误
- linux - 在gnuplot中将y轴分成三个部分
- c# - 如何在 C# 中使用线程安全列表?
- jquery - 调用添加分类 jquery
- node.js - Angular 您可能需要适当的加载程序错误
- php - Woocommerce - 在 CHECKOUT 中模拟“运送到不同的地址?”以更新订单货币
- dart - DropdownButton 没有改变 onChanged 的值
- javascript - 在 MongoDB 查找函数中,我回调并使用 res.redirect,我得到一个无法设置标头错误?
- c# - 引入 FOREIGN KEY 约束“XXX”......无法创建约束或索引
- java - Task-Runnable-、Thread-、Timeline 对象是线程安全的吗?