Django查询查询?

问题描述:

试图加快我的应用程序的性能,并用调试工具栏发布一些分析我可以看到我正在做68个查询。Django查询查询?

我查询每个展厅(68)的电路,我想如果我只是查询电路一次,然后我可以重新查询现有的查询,而不是再次为每个电路调用DB?

像添加:

crData = Circuits.objects.only('circuit_preference','site_data__id') 

如何再次查询CRDATA?以匹配每一个陈述?下面

# get shworoom data 
srData = SiteData.objects.only('location','subnet').filter(is_live=True).exclude(site_type='Major Site') 

for sr in srData: 
    site = SiteType() 
    site.type = checkRoute(sr.subnet) 
    site.location = sr.location 

    if 'MPLS' in site.type: 
     mpls = site.type.split('-') 
     try: 

      d = Circuits.objects.only('circuit_preference','site_data').filter(site_data__id=sr.id,provider=mpls[0],circuit_type__icontains=mpls[1]) 
      site.preference = d[0].circuit_preference 
     except: 
      pass 
    elif site.type == '4G': 
     try: 
      d = Circuits.objects.only('circuit_preference','site_data').filter(site_data__id=sr.id,provider='EE',circuit_type__icontains=site.type) 
      site.preference = d[0].circuit_preference 
     except: 
      pass  
    elif site.type == 'DSL' or site.type == 'FIBRE': 
     try: 
      d = Circuits.objects.only('circuit_preference','site_data').filter(site_data__id=sr.id,circuit_type__icontains=site.type) 
      site.preference = d[0].circuit_preference 
     except: 
      pass 

当前码**编辑:下面

class SiteData(models.Model): 
    location = models.CharField(max_length=50) 
    site_type = models.CharField(max_length=20, verbose_name="Site Type", \ 
       choices=settings.SITE_TYPE) 
    subnet = models.GenericIPAddressField(protocol='IPv4') 
    bgp_as = models.CharField(max_length=6, verbose_name="BGP AS Number") 
    opening_date = models.DateField(verbose_name="Showroom 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?") 
    tel = models.CharField(max_length=20, blank=True, null=True) 
    notes = models.TextField(blank=True) 
    class Meta: 
     verbose_name = "Site Data" 
     verbose_name_plural = "Site Data" 
     ordering = ('location',) 

    def __unicode__(self): 
     return self.location 

class Circuits(models.Model): 
    site_data = models.ForeignKey(SiteData, verbose_name="Site", on_delete=models.PROTECT) 
    order_no = models.CharField(max_length=200, verbose_name="Order No") 
    install_date = models.DateField(blank=True, null=True) 
    circuit_type = models.CharField(max_length=100, choices=settings.CIRCUIT_CHOICES) 
    circuit_preference = models.CharField(max_length=20, verbose_name="Circuit Preference", \ 
         choices=settings.CIRCUIT_PREFERENCE, blank=True, null=True) 
    circuit_speed_down = models.DecimalField(max_digits=10, decimal_places=1, blank=True, null=True) 
    circuit_speed_up = models.DecimalField(max_digits=10, decimal_places=1, blank=True, null=True) 
    circuit_bearer = models.IntegerField(blank=True, null=True) 
    provider = models.CharField(max_length=200, choices=settings.PROVIDER_CHOICES) 
    ref_no = models.CharField(max_length=200, verbose_name="Reference No") 
    cost_per_month = models.DecimalField(decimal_places=2, max_digits=8) 
    contract_length = models.IntegerField(verbose_name="Contact length in years") 
    service_contacts = models.ForeignKey(ServiceContacts, on_delete=models.PROTECT) 
    subnet = models.GenericIPAddressField(protocol='IPv4', verbose_name="Subnet", \ 
      blank=True, null=True) 
    default_gateway = models.GenericIPAddressField(protocol='IPv4', \ 
         verbose_name="Default Gateway", blank=True, null=True) 
    subnet_mask = models.CharField(max_length=4, verbose_name="Subnet Mask", \ 
        choices=settings.SUBNET_MASK_CHOICES, blank=True, null=True) 
    internet_device = models.ForeignKey(ConfigTemplates, \ 
         verbose_name="is this circuit the active internet line for a device?", \ 
         default=6, on_delete=models.PROTECT) 
    decommissioned = models.BooleanField(default=False, verbose_name="Decomission this circuit?") 
+3

显示您的机型。 –

+0

@DanielRoseman在上面加上了坦克 – AlexW

我要指出你走向Pickling,但我想,除非你需要缓存是没有意义的模型该查询集将在另一个位置重新使用。

其实我很肯定querysets are pretty good for only hitting the database when they need to,这是他们第一次评估时。但是,我认为重新声明queryset会导致它被重新评估,但是如果你创建了一个查询集列表/字典,我想你应该能够重新使用它们而不用再次访问数据库(除非你需要运行新的过滤器)。所以我不认为你每次访问crData查询集时都会敲击数据库,但是至少应该能够存储查询集并重用它们,而不必为每个数据库点击数据库再一次。

这样的事情应该工作,我认为。想知道我是否错了。

crData = [] 
for sr in srData: 
    # ... 
    crData.append(d) 

for cr in crData: 
    # Do stuff 

编辑:下面是另一个相关的问题:Django ORM and hitting DB


+0

唯一的问题是我需要重新查询数据,我希望能得到所有的电路一次,然后查询我的if语句中的数据如上 – AlexW

+0

呵呵,你只是想迭代crData不止一次,并检查它的领域? –

+0

是的,阅读,虽然它表明覆盖到列表会比运行68个查询有更差的性能影响? – AlexW