Python Django ORM:如何使用相关模型上的子查询过滤一个模型
我在引用django子查询中的外部字段时遇到了问题,在SQL中很容易做到这一点。我有这两种型号:Python Django ORM:如何使用相关模型上的子查询过滤一个模型,python,django,Python,Django,我在引用django子查询中的外部字段时遇到了问题,在SQL中很容易做到这一点。我有这两种型号: class Modem(models.Model): mac = Models.LowerCaseCharField class DHCPEvent(models.Model): timestamp = models.DateTimeField() # date released modem = models.ForeignKey(Modem) ip = model
class Modem(models.Model):
mac = Models.LowerCaseCharField
class DHCPEvent(models.Model):
timestamp = models.DateTimeField() # date released
modem = models.ForeignKey(Modem)
ip = models.LowerCaseCharField()
将IP分配给给定调制解调器a的时间窗口为:[将IP分配给调制解调器a时的时间戳,将IP分配给另一个调制解调器时的时间戳]。我希望能够查询与搜索时间窗口重叠的特定调制解调器的所有IP分配(调制解调器,从\u日期到\u日期->[ips])
为此,我认为我需要在时间窗口结束之前找到分配给调制解调器的DHCPEvent,然后,对于每个DHCPEvent,在搜索时间窗口开始之前,确认其IP没有分配给其他地方的DHCPEvent。这定义了IP到调制解调器的分配与搜索窗口重叠。但我不确定在Django中如何做。什么到目前为止,我得到的是:
Modem.objects.filter(
dhcpevent__ip=Subquery(
DHCPEvent.objects.filter(
ip=OuterRef('dhcpevent__ip'),
timestamp__gt=OuterRef('dhcpevent__timestamp'),
timestamp__lte=to_date)))
有两个问题:
select
*
from
"MODEM" modem
inner join "DHCPEVENT" dhcp_event_assign
on modem."ID" = dhcp_event_assign."MODEM_ID"
where
modem."ID" = %(id)s
dhcp_event_assign."TIMESTAMP" <= %(to_date)s and
not exists(
select
*
from
"DHCPEVENT" dhcp_event_next
where
dhcp_event_next."REMOTE_ADDRESS" = dhcp_event_assign."REMOTE_ADDRESS"
and dhcp_event_next."TIMESTAMP" > dhcp_event_assign."TIMESTAMP"
and dhcp_event_next."TIMESTAMP" <= %(from_date)s
and not ( dhcp_event_next."MODEM_ID" = modem."ID" )
)
选择
*
从…起
“调制解调器”调制解调器
内部联接“DHCPEVENT”dhcp\u事件\u分配
在调制解调器上。“ID”=dhcp\u事件\u分配。“调制解调器\u ID”
哪里
调制解调器。“ID”=%(ID)s
dhcp事件分配。“时间戳”dhcp事件分配。“时间戳”
我不确定我是否理解你的问题。但是是什么阻止你使用Modem.objects.filter(dhcpevent\uuu ip=the\u ip,dhcp\uu TIMESTAMP\uu gt=TIMESTAMP,dhcp\uu TIMESTAMP\uu lte=to\u date)
?这不起作用,因为如果DHCP租约在搜索查询时间窗口之前开始,在搜索查询时间窗口之后结束,则此查询将找不到它,因为即使租约窗口重叠,也没有实际事件。但在这种情况下,子查询无法解决任何问题。您只是在另一个时间窗口内执行查询。如果您要确保不会错过任何DHCP租约s、 您需要研究一种锁定机制,该机制将在查询完成之前停止租用IP。在我看来,这种方法更简单、更准确。我想可能有一个误解-您是在谈论原子搜索中的锁定?还是我遗漏了什么?该查询的问题是,如果我有,例如,调制解调器的租约分配A在8月1日,然后在8月30日分配给另一个调制解调器,并搜索调制解调器A从8月10日到8月15日的租约,您的查询将找不到租约,即使它与时间窗口重叠。因此(我认为)我需要子查询DHCPEvent表,以查看该IP的下一个事件。不,我的意思是,在开始筛选查询之前,禁用不允许任何IP租用,直到完成为止,然后在获得结果后,恢复租用IP。