【问题标题】:Convert a complex SQL query in Django ORM在 Django ORM 中转换复杂的 SQL 查询
【发布时间】:2021-09-07 17:45:45
【问题描述】:

在我的项目中,我有一个 SQL 查询,用于从像这样的两个表中提取一些结果:

SELECT
    read_date, unit_id, device_id, proj_code, var_val
FROM
    public.api_site_varsresults AS SV, public.api_site_results AS SR
WHERE 
    (read_date >= '2021-06-21' AND read_date <= '2021-06-24') AND SV.id_res_id = SR.id

这里是我的模型:

class Results(models.Model):
    id = models.AutoField(primary_key=True)
    device = models.ForeignKey(Device, null=True, on_delete=models.SET_NULL)
    proj_code = models.CharField(max_length=400)
    res_key = models.SlugField(max_length=80, verbose_name="Message unique key", unique=True)
    read_date = models.DateTimeField(verbose_name="Datetime of vals readings")
    unit = models.ForeignKey(ModbusDevice, null=True, on_delete=models.SET_NULL)

    def __str__(self):
        return self.device

    class Meta:
        indexes = [
            models.Index(fields=['device', 'unit', 'proj_code']),
        ]


class VarsResults(models.Model):
    id = models.AutoField(primary_key=True)
    id_res = models.ForeignKey(Results, related_name="mainres", on_delete=models.CASCADE)
    var_id = models.ForeignKey(ModbusVariable, null=True, on_delete=models.SET_NULL)
    var_val = models.CharField(max_length=400, blank=True)
    var_hash = models.CharField(max_length=400)

    def __str__(self):
        return self.var_hash

    class Meta:
        indexes = [
            models.Index(fields=['id_res', 'var_id']),
        ]

我想在使用 ORM 的 django 项目中使用此查询,但我尝试这样做:

varsresults.objects.filter(<conditions>).fields(<fields>)

但不正确,我不知道如何链接两个表,选择特定字段并在 django ORM 中过滤该条件

有人可以帮帮我吗? 提前非常感谢

曼努埃尔

【问题讨论】:

  • 向我们展示您的模型。
  • 好的,我做到了。谢谢

标签: sql django django-orm


【解决方案1】:

您的 Django 查询将是:

start_date = datetime.date(2021, 06, 21)
end_date = datetime.date(2021, 06, 24)
var_results = VarsResults.objects.filter(
    id_res__read_date__range=(start_date, end_date)
).select_related(
    "id_res"
).values(
    "id_res__read_date",
    "id_res__unit_id",
    "id_res__device_id",
    "id_res__proj_code",
    "var_val",
)

或者在查询期间访问字段而不获取值:

start_date = datetime.date(2021, 06, 21)
end_date = datetime.date(2021, 06, 24)
var_results = VarsResults.objects.filter(
    id_res__read_date__range=(start_date, end_date)
).select_related(
    "id_res"
)

read_date = var_results.id_res.read_date
unit_id = var_results.id_res.unit_id

阅读 here 关于 select_related 的信息。

阅读here 了解.values() 以及如何访问相关字段。

有关__range,请参阅here

【讨论】:

  • 谢谢,但我明白了:无法将关键字“read_date”解析为字段。选项有:id、id_res、id_res_id、var_hash、var_id、var_id_id、var_val
  • 对不起,我的.filter() 错了,我已经更新了答案。
猜你喜欢
  • 2012-08-03
  • 1970-01-01
  • 2013-06-09
  • 2021-07-06
  • 1970-01-01
  • 2016-04-20
  • 2021-05-27
  • 2020-09-12
相关资源
最近更新 更多