2011-01-05 100 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