我有以下模型
class Scheduler(models.Model):
id = <this is primary key>
last_run = <referencing to id in RunLogs below>
class RunLogs(models.Model):
id = <primary key>
scheduler = <referencing to id in Scheduler above>
overall_status = <String>
仅当scheduler
达到作业的预定时间时,才会创建RunLogs
条目。
现在我在RunLogs上查询以显示如下的运行时间表。
current = RunLog.objects\
.filter(Q(overall_status__in = ("RUNNING", "ON-HOLD", "QUEUED") |
Q(scheduler__last_run__isnull = True))
以上查询为我提供了RunLogs
匹配状态的所有记录,但未向Scheduler
提供last_run
is null
的记录。
我理解为什么查询的行为如此,但有没有办法从scheduler
获取last_run is null
的记录
?
答案 0 :(得分:1)
我刚刚执行了您所遵循的相同步骤,并找到了运行查询后获取所有记录的原因。以下是确切的步骤和解决方案。
创建模型
from django.db import models
class ResourceLog(models.Model):
id = models.BigIntegerField(primary_key=True)
resource_mgmt = models.ForeignKey('ResourceMgmt', on_delete=models.DO_NOTHING,
related_name='cpe_log_resource_mgmt')
overall_status = models.CharField(max_length=8, blank=True, null=True)
class ResourceMgmt(models.Model):
id = models.BigIntegerField(primary_key=True)
last_run = models.ForeignKey(ResourceLog, on_delete=models.DO_NOTHING, blank=True, null=True)
添加如下数据:
resource_log
+----+----------------+------------------+
| id | overall_status | resource_mgmt_id |
+----+----------------+------------------+
| 1 | RUNNING | 1 |
| 2 | QUEUED | 1 |
| 3 | QUEUED | 1 |
+----+----------------+------------------+
resource_mgmt
+----+-------------+
| id | last_run_id |
+----+-------------+
| 1 | NULL |
| 2 | NULL |
| 3 | NULL |
| 4 | 3 |
+----+-------------+
根据上面的表,resource_mgmt(4)指的是resource_log(3)。但值得注意的是,resource_log(3)并未引用resource_mgmt(4)。
在python shell中运行以下命令
In [1]: resource_log1 = ResourceLog.objects.get(id=1)
In [2]: resource_log.resource_mgmt
Out[2]: <ResourceMgmt: ResourceMgmt object (1)>
In [3]: resource_log1 = ResourceLog.objects.get(id=2)
In [4]: resource_log.resource_mgmt
Out[4]: <ResourceMgmt: ResourceMgmt object (1)
In [5]: resource_log1 = ResourceLog.objects.get(id=3)
In [6]: resource_log.resource_mgmt
Out[6]: <ResourceMgmt: ResourceMgmt object (1)>
从中我们可以理解所有resource_log对象都引用了resource_mgmt的第一个对象(即id = 1)。
问)为什么所有对象都引用了resource_mgmt中的第一个对象?
resource_mgmt是非空的外键字段。创建resource_log对象时,其默认值为1.如果未指定resource_mgmt,则会在此处添加默认值1。
运行查询
In [60]: ResourceLog.objects.filter(resource_mgmt__last_run__isnull = True)
Out[60]: <QuerySet [<ResourceLog: ResourceLog object (1)>, <ResourceLog: ResourceLog object (2)>, <ResourceLog: ResourceLog object (3)>]>
此查询返回所有三个ResourceLog对象,因为这三个对象都引用了第一个resource_mgmt对象,其
is_null
值为True
你实际上想检查反向关系。
我们可以使用两个查询来实现这一目标:
rm_ids = ResourceMgmt.objects.exclude(last_run=None).values_list('last_run', flat=True)
current = ResourceLog.objects.filter(overall_status__in = ("RUNNING", "QUEUED")).exclude(id__in=rm)
输出结果为:
<QuerySet [<ResourceLog: ResourceLog object (1)>, <ResourceLog: ResourceLog object (2)>]>
希望有所帮助!