Django ORM 相当于此 SQL..从相关表派生的计算字段
我的模型结构如下:
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 对其进行编码?
I have the following model structure below:
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)
The goal is to produce a queryset that returns all the fields from MLog plus a calculated field (item_height) based on the related data in Master
using Django's raw 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
''')
How do I code this using Django's ORM?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我可以想到两种不依赖
raw()
的方法来解决这个问题。第一个与 @tylerl 建议。像这样的事情:在本例中,我为
MLog
定义一个名为item_height
的自定义(派生)属性。此属性的计算方式为实例的sensor_reading
与其相关主实例的 Mounting_height 之差。有关属性
的更多信息此处。然后,您可以执行以下操作:
第二种方法是使用
extra()
方法并拥有数据库为你计算一下。您会注意到
select_lated()
的使用。如果没有这个,Master
表将不会与查询连接,并且您将收到错误。I can think of two ways to go about this without relying on
raw()
. The first is pretty much the same as what @tylerl suggested. Something like this:In this case I am defining a custom (derived) property for
MLog
calleditem_height
. This property is calculated as the difference of thesensor_reading
of an instance and the mounting_height of its related master instance. More onproperty
here.You can then do something like this:
The second way to do this is to use the
extra()
method and have the database do the calculation for you.You'll note the use of
select_related()
. Without this theMaster
table will not be joined with the query and you will get an error.我总是在应用程序中而不是在数据库中进行计算。
然后,您可以像操作任何其他字段一样操作它,并且它会执行您使用基础数据定义的任何操作。例如:
顺便说一句,Property只是一个标准的属性装饰器,在本例中编码如下(我不记得它来自哪里):
I always do the calculations in the app rather than in the DB.
Then you can manipulate it just as you would any other field, and it does whatever you defined with the underlying data. For example:
Property, by the way, is just a standard property decorator, in this case coded as follows (I don't remember where it came from):