如何使用django join为结果中返回的每个id选择customer_name

时间:2014-10-20 16:30:46

标签: python django django-models django-views

我一直在研究django加入,我可以看到如何用.select_related选择相关字段,但我似乎无法按照我想要的方式工作。我基本上有使用customer_id FK链接到customers表的汇总表,我想从customers字段中为每个汇总返回的每个值选择客户名称。

我添加了伪代码来显示我想要做的事情。

sql would be = ''' select a.customer_name, b.vm_name, b.vm_cpu, b.vm_mem from customers a, vms b where a.customer_id = b.customer_id'''

我如何用django做到这一点。这样我循环返回值

for value in sql:
    list.append(value.1, value.2, value.3)

这样我可以将customer_name与每个字段关联并输出。

这是我想要做的事情:

 compute_usages_related = ComputeUsages.objects.filter(customer_id = customer_id).filter(load_date = datetime(year, day, selected_month)).select_related('customer_name')
 test_related = []
 for row in compute_usages_related:
    test_related.append(row.customer_name)
显然,这不起作用。

基本上是针对特定客户的,但有一种情况是,拥有管理员权限的公司员工可以查询整个数据库以查找所有客户并创建使用情况报告,因此我需要将customer_names与查询相关联。

有关如何使用django执行此操作的任何想法?

型号:

class Customers(models.Model):
    customer_id = models.BigIntegerField(primary_key=True, editable=False)
    customer_name = models.CharField(max_length=100)
    inactive = models.CharField(max_length=1)
    datetime = models.DateTimeField()
    class Meta:
        managed = True
        db_table = 'customers'

    def __unicode__(self):  # Python 3: def __str__(self):
      return self.customer_name

    def clean(self):
      if self.inactive != 'Y' and self.inactive != 'N':
         raise ValidationError('Please enter a Y or N')

class ComputeUsages(models.Model):
    compute_usage_id = models.AutoField(primary_key=True, editable=False)
    customer = models.ForeignKey(Customers)
    vm_name = models.CharField(max_length=4000)
    vm_id = models.BigIntegerField()
    core_hours = models.DecimalField(max_digits=15, decimal_places=2)
    ram_hours = models.DecimalField(max_digits=15, decimal_places=2)
    guest_os = models.CharField(max_length=100)
    provisioned_cores = models.BigIntegerField()
    provisioned_ram = models.BigIntegerField()
    load_date = models.DateField()
    datetime = models.DateTimeField()

    class Meta:
        managed = True
        db_table = 'compute_usages'

    def __unicode__(self):  # Python 3: def __str__(self):
      return self.vm_name

1 个答案:

答案 0 :(得分:1)

您可以已经执行以下操作,而不使用select_related

test_related.append(row.customer.customer_name)

因为它只使用您已经定义的字段。但是,这是非常低效的,因为它为每一行生成一个新的数据库查询。所有select_related都通过对Customer表执行JOIN来预缓存该值。再次注意,它是您要查询的表,而不是列:

compute_usages_related = ComputeUsages.objects....select_related('customer')

(为清楚起见,我删除了过滤条款)。而且,再次访问列的方式不会改变:您仍然执行row.customer.customer_name,只是不再需要额外的数据库查询。

如果您开始将模型视为类而不是SQL查询,那么这对您来说将更加清晰。另外,您应该充分利用Python shell来探索对象的属性。