为什么要执行2个查询而不是1个?

时间:2014-04-07 04:59:41

标签: mysql django

我有以下代码:

def detail(request, popular_id):
   try:
      popular = Popular.objects.get(pk = popular_id)
      share = Share.objects.get(isin = popular.isin) #LINE 1
      chart_data_json = share.get_chart_data_json()
   except Popular.DoesNotExist:
      raise Http404
   return render(request, 'popular/detail.html', {'popular': popular, 'chart_data': chart_data_json})

在第1行中,我注意到使用调试工具栏会执行两个查询:

SELECT `share_share`.`id`, `share_share`.`symbol`, `share_share`.`isin`, `share_share`.`name`, `share_share`.`market`, `share_share`.`updated` FROM `share_share` WHERE `share_share`.`id` = 1

SELECT `share_share`.`id`, `share_share`.`symbol`, `share_share`.`isin`, `share_share`.`name`, `share_share`.`market`, `share_share`.`updated` FROM `share_share` WHERE `share_share`.`isin` = 'US5949181045'

我无法理解为什么我们需要第一个查询以及如何避免它?

编辑:

分享的模型定义:

class Share(models.Model):
   symbol = models.CharField(max_length = 32)
   isin = models.CharField(max_length = 12)
   name = models.CharField(max_length = 256)
   market = models.CharField(max_length = 64)
   updated = models.BooleanField(default = False)

   def get_chart_data_json(self):
      quote_model = create_quote_model(str(self.isin))
      data = quote_model.objects.values('date', 'adj_close', 'volume')
      chart_data = []
      for d in data.iterator():
         chart_data.append({'date': d['date'].isoformat(), 'value': d['adj_close'], 'volume': d['volume']})
      chart_data_json = json.dumps(chart_data)
      return chart_data_json

   def __unicode__(self):
      return self.isin

流行的模型定义:

class Popular(models.Model):
   title = models.CharField(max_length = 120)
   text = models.CharField(max_length = 1024)
   isin = models.ForeignKey(Share)

   def __unicode__(self):
      return self.title

1 个答案:

答案 0 :(得分:1)

  1. 从流行对象访问外键isin时,将评估第一个查询:

    share = Share.objects.get(isin = popular.isin

  2. 第二个查询获取Share对象:

    share = Share.objects.get (isin = popular.isin)

  3. 如果您只想在#LINE 1处进行一次查询,则应将其替换为:

    share = popular.isin #LINE 1