Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django ORM:如何使用相关模型上的子查询过滤一个模型_Python_Django - Fatal编程技术网

Python Django ORM:如何使用相关模型上的子查询过滤一个模型

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

我在引用django子查询中的外部字段时遇到了问题,在SQL中很容易做到这一点。我有这两种型号:

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)))
有两个问题:

  • 它抛出了“ValueError:此查询集包含对外部查询的引用,并且只能在子查询中使用。”在我看来,它似乎位于子查询内部
  • 我需要OuterRefs只查看第二行中第一个引用的DHCPEvent,而不是连接到此调制解调器的每个DHCPEvent。但我不知道如何表达这一点
  • 谢谢你的建议,谢谢

    编辑:我现在已经用SQL编写了这个查询,这可能会大大澄清我在Django中试图实现的目标:

    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。