2011-01-05 73 views
0

我有另一个Django/python问题。我有一个models.py,看起来像这样。关于查询集的Django问题

class Client(models.Model): 
client_number = models.PositiveIntegerField() 
name = models.CharField(max_length=80) 
address = models.CharField(max_length=250) 
telephone = models.CharField(max_length=20) 
fax = models.CharField(max_length=20) 
email = models.EmailField() 
alternative_name = models.CharField(max_length=80, blank=True, null=True) 
alternative_address = models.CharField(max_length=250, blank=True, null=True) 
alternative_telephone = models.CharField(max_length=20, blank=True, null=True) 
alternative_email = models.EmailField(blank=True, null=True) 
def __unicode__(self): 
     return unicode(self.client_number) 

class Contract(models.Model): 
client_number = models.ForeignKey(Client) 
client_contract_number = models.PositiveIntegerField() 
start_date = models.DateField() 
end_date = models.DateField() 
contract_type = models.IntegerField(verbose_name = "Contract Types", choices = CONTRACT_TYPE_CHOICES) 
contract_status =models.IntegerField(verbose_name = "Contract Status", choices = CONTRACT_STATUS_CHOICES) 
exception = models.DecimalField(max_digits=5, decimal_places=2) 
uplift_percentage = models.DecimalField(max_digits=5, decimal_places=2) 
payment_day = models.DateField() 
payment_type = models.IntegerField(verbose_name = "Payment Type", choices = PAYMENT_TYPE_CHOICES) 
late_payment = models.IntegerField(verbose_name = "Late Payment Change", choices = LATE_PAYMENT_CHOICES) 
late_payment_change_rate = models.DecimalField(max_digits=5, decimal_places=2) 
contract_value = models.DecimalField(max_digits=20, decimal_places=2) 
monthly_value = models.DecimalField(max_digits=20, decimal_places=2) 

def __unicode__(self): 
     return unicode (self.client_contract_number) 


    class Invoice(models.Model): 
    transaction_type = models.IntegerField(verbose_name = "Transaction type", choices = TRANSACTION_TYPE_CHOICES) 
    invoice_number = models.CharField(max_length=16) 
    date = models.DateField() 
    client_contract_number = models.ForeignKey(Contract) 
    invoice_contact = models.CharField(max_length=80) 
    invoice_net = models.DecimalField(max_digits=16, decimal_places=2) 
    invoice_vat = models.DecimalField(max_digits=16, decimal_places=2) 
    invoice_gross = models.DecimalField(max_digits=16, decimal_places=2) 
    payment_date = models.DateField() 
    special_notes = models.CharField(max_length=128) 

    def __unicode__(self): 
      return self.invoice_number 

我知道在Django,如果我找{{invoices.client_contract_number }},我得到了客户的合同编号。但假设我想知道某个特定的发票,我将如何查看客户名称是?我无法{{invoice.name}},因为发票中的客户端没有任何foregin键值。

编辑: 这是我的观点

@login_required 
def homepage(request): 
    invoices_list = Invoice.objects.all() 
    invoice_name = invoices_list.client_contract_number.client_number.name 
    return render_to_response(('index.html', locals()), {'invoices_list': invoices_list }, context_instance=RequestContext(request)) 

和错误。

'QuerySet' object has no attribute 'client_contract_number' 

回答

2

您可以按照关系跨两个连接:

invoice.client_contract_number.client_number.name 

顺便说一句,你的字段名混乱。 client_contract_number不是一个数字,它是一个合同。并且client_number也不是一个数字,它是一个客户端。请致电client_contractclient。问题更新

编辑我不知道你想在这里做什么。 invoices_list是所有发票的查询集合 - 显然,询问客户名称是否为列表没有任何意义。想必你真正想要做的是遍历 - 可能在你的模板 - 以及每一个打印的名字:

{% for invoice in invoices_list %} 
    Client name: {{ client_contract_number.client_number.name }} 
{% endfor %} 
+0

'client_contract_number'对我来说看起来像一个数字。 'client_number'不会。 – 2011-01-05 10:46:10

+0

@Dominic Roger:有两个字段叫'client_contract_number'。 “Invoice”模型中的一个是ForeignKey,“Contract”中的是一个整数。 – 2011-01-05 10:49:46

+0

我想我以前尝试过这样的东西,但它没有奏效。我认为这是我在views.py中写的。我的观点需要什么? – Shehzad009 2011-01-05 10:53:56

0
def homepage(request): 
    invoices_list = Invoice.objects.all() 
    invoice_name = invoices_list.client_contract_number.client_number.name 
    return render_to_response(('index.html', locals()), {'invoices_list': invoices_list }, context_instance=RequestContext(request)) 

不能从发票列表获取客户端的名字。是否有您感兴趣的特定发票?

当你有一个发票的实例,那么你可以做invoice.client_contract_number.client_number.name。但是你不能在清单上做到这一点!顺便说一下,如果你要遍历多个连接,请确保你的查询集有一个select_related子句。

invoices_list = Invoice.objects.select_related(depth=3).all() 

这将确保,如果你在列表中迭代,然后做每个对象3的关系查询只有一个大的查询被执行了前面,而不是潜在的数百人。任何时候你有超过1 dot(invoice.client是一个点),强烈考虑使用select_related。

+0

基本上我想显示一个表格,其中一列将显示所有发票编号。应该在另一列显示所有客户名称。但是,正确的发票编号必须与同一行中正确的客户名称匹配。 – Shehzad009 2011-01-05 12:18:37

+0

@Sheh我明白你在做什么。接受的答案是正确的。您应该通过使用点语法跨越多个关系通过发票获取客户名称。这应该在模板中完成。不在你看来。在迭代发票时,您需要提取发票客户名称属性。尽管我对select_related的建议仍然是很好的建议。在您的视图中使用select_related,并访问模板中的客户端名称。 – 2011-01-05 21:49:36