Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.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-按id连接两个查询集?_Python_Django - Fatal编程技术网

Python Django-按id连接两个查询集?

Python Django-按id连接两个查询集?,python,django,Python,Django,我试图在发送到视图之前将两个表连接在一起,在视图中使用_set会导致100次查询,这是非常低效的 示例结构sites.models.py class SiteData(models.Model): location = models.CharField(max_length=50) site_type = models.ForeignKey(SiteTypes, verbose_name="Site Type", \ on_delete=model

我试图在发送到视图之前将两个表连接在一起,在视图中使用_set会导致100次查询,这是非常低效的

示例结构sites.models.py

class SiteData(models.Model):
    location = models.CharField(max_length=50)
    site_type = models.ForeignKey(SiteTypes, verbose_name="Site Type", \
                on_delete=models.PROTECT)
    bgp_as = models.CharField(max_length=6, verbose_name="BGP AS Number")
    opening_date = models.DateField(verbose_name="Site opening date")
    last_hw_refresh_date = models.DateField(verbose_name="Date of latest hardware refresh", \
                           blank=True, null=True)
    is_live = models.BooleanField(default=False, verbose_name="Is this a live site?")
class SiteSubnets(models.Model):
    site_data = models.ForeignKey(SiteData, verbose_name="Location", \
                on_delete=models.PROTECT, blank=True, null=True)               
    subnet = models.GenericIPAddressField(protocol='IPv4', \
             verbose_name="Subnet", blank=True, null=True)
    subnet_type = models.ForeignKey(SubnetTypes, verbose_name="Subnet Type") 
    vlan_id = models.IntegerField(verbose_name="Vlan ID", blank=True, null=True)
    peer_desc = models.IntegerField(verbose_name="Peer description", blank=True, null=True)
    site_ip = models.BooleanField(default=False, verbose_name="Is this a site supernet IP?")
    class Meta:
        verbose_name = "Site Subnets"
        verbose_name_plural = "Site Subnets"
示例结构config.models.py

class SiteData(models.Model):
    location = models.CharField(max_length=50)
    site_type = models.ForeignKey(SiteTypes, verbose_name="Site Type", \
                on_delete=models.PROTECT)
    bgp_as = models.CharField(max_length=6, verbose_name="BGP AS Number")
    opening_date = models.DateField(verbose_name="Site opening date")
    last_hw_refresh_date = models.DateField(verbose_name="Date of latest hardware refresh", \
                           blank=True, null=True)
    is_live = models.BooleanField(default=False, verbose_name="Is this a live site?")
class SiteSubnets(models.Model):
    site_data = models.ForeignKey(SiteData, verbose_name="Location", \
                on_delete=models.PROTECT, blank=True, null=True)               
    subnet = models.GenericIPAddressField(protocol='IPv4', \
             verbose_name="Subnet", blank=True, null=True)
    subnet_type = models.ForeignKey(SubnetTypes, verbose_name="Subnet Type") 
    vlan_id = models.IntegerField(verbose_name="Vlan ID", blank=True, null=True)
    peer_desc = models.IntegerField(verbose_name="Peer description", blank=True, null=True)
    site_ip = models.BooleanField(default=False, verbose_name="Is this a site supernet IP?")
    class Meta:
        verbose_name = "Site Subnets"
        verbose_name_plural = "Site Subnets"
查询:

site_subnets = SiteSubnets.objects.only('subnet').filter(site_ip=True)
site_data = SiteData.objects.only('location','is_live','bgp_as','postcode','opening_date','live_link_type')
预期结果示例:

Location   | Subnet     | BGP AS
---------------------------------
London     | 10.10.10.0 | 65001
Manchester | 10.10.20.0 | 65002
...
如果不将sitesubnet表作为主表,我无法执行与select_相关的操作,因为当我对站点数据执行此操作时,我会得到

django.core.exceptions.FieldError: Invalid field name(s) given in select_related: 'site_subnets'. Choices are: site_type
如果我使用SiteSubnet作为主表,如果站点没有SiteSubnet.Site\u up,我将无法获取站点信息。展示

有人知道一种方法可以显示所有数据而不运行n+1查询吗

编辑:

预取也会失败,出现以下错误:

AttributeError: Cannot find 'site_subnets_set' on SiteData object, 'site_subnets_set' is an invalid parameter to prefetch_related()
我会将数据发送到一个模板,以便在循环中访问,即

<table>
  <tr>
    <td>Location</td>
    <td>Subnet</td>
    <td>BGP AS</td>  
  <tr>
{%for site in sitedata %}
  <tr>
    <td>{{ site.location }}</td>
    <td>{{ site.subnet }}</td>
    <td>{{ site.bg_as }}</td>  
  <tr>
{% endfor %}
谢谢

您可以在sitedata queryset中使用与预回迁SiteSubnet相关的预回迁

SiteData.objects.prefetch_related('sitesubnets_set')

是否可以使用SiteData.objects.prefetch_相关的“sitesubnets_set”?如果在循环中运行site\u data.sitesubnets\u set.all,则应防止n+1查询。如何显示它?你可以在你的站点子网查询集上做一个for循环,然后从每个元素访问站点数据……你没有尝试我建议的。您使用了site\u subnets\u set而不是sitesubnets\u set。我的错误,这很有效!谢谢你