gpt4 book ai didi

django - 从相关表派生的此SQL..calculated字段的Django ORM等效项

转载 作者:行者123 更新时间:2023-12-02 07:51:13 24 4
gpt4 key购买 nike

我的模型结构如下:

class Master(models.Model): 
name = models.CharField(max_length=50)
mounting_height = models.DecimalField(max_digits=10,decimal_places=2)

class MLog(models.Model):
date = models.DateField(db_index=True)
time = models.TimeField(db_index=True)
sensor_reading = models.IntegerField()
m_master = models.ForeignKey(Master)

目标是生成一个查询集,该查询集返回MLog中的所有字段以及基于Master中相关数据的计算字段(item_height)

使用Django的原始sql:
querySet = MLog.objects.raw('''
SELECT a.id,
date,
time,
sensor_reading,
mounting_height,
(sensor_reading - mounting_height) as item_height
FROM db_mlog a JOIN db_master b
ON a.m_master_id = b.id
''')

如何使用Django的ORM编写此代码?

最佳答案

我可以想到两种不依赖raw()的方法。第一个与@tylerl suggested几乎相同。像这样:

class Master(models.Model):
name = models.CharField(max_length=50)
mounting_height = models.DecimalField(max_digits=10,decimal_places=2)

class MLog(models.Model):
date = models.DateField(db_index=True)
time = models.TimeField(db_index=True)
sensor_reading = models.IntegerField()
m_master = models.ForeignKey(Master)

def _get_item_height(self):
return self.sensor_reading - self.m_master.mounting_height
item_height = property(_get_item_height)

在这种情况下,我将为 MLog定义一个自定义(派生)属性,称为 item_height。此属性的计算方式是实例的 sensor_reading和其相关主实例的mounting_height的差。有关 property here的更多信息。

然后,您可以执行以下操作:
In [4]: q = MLog.objects.all()

In [5]: q[0]
Out[5]: <MLog: 2010-09-11 8>

In [6]: q[0].item_height
Out[6]: Decimal('-2.00')

第二种方法是使用 extra() 方法,并让数据库为您进行计算。
In [14]: q = MLog.objects.select_related().extra(select = 
{'item_height': 'sensor_reading - mounting_height'})

In [16]: q[0]
Out[16]: <MLog: 2010-09-11 8>

In [17]: q[0].item_height
Out[17]: Decimal('-2.00')

您会注意到 select_related()的使用。没有这个, Master表将不会与查询结合在一起,并且您将得到一个错误。

关于django - 从相关表派生的此SQL..calculated字段的Django ORM等效项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3690343/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com