2011-01-05 3 views
0

Ich habe eine andere Django/Python Frage. Ich habe ein models.py, die ungefähr so ​​aussehen.Django Frage zu Querysets

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 

ich in django, ob ich für {{invoices.client_contract_number }} aussehen, erhalte ich die Client-Vertragsnummer. Aber angenommen, ich möchte für eine bestimmte Rechnung wissen, wie würde ich den Namen des Kunden nachschlagen? Ich kann {{invoice.name}} nicht ausführen, da für den Kunden in der Rechnung kein Vorgängerschlüsselwert vorhanden ist.

Edit: Hier ist meine Ansichten

@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)) 

und Irrtum.

'QuerySet' object has no attribute 'client_contract_number' 

Antwort

2

Sie die Beziehung folgen kann über zwei verbindet:

invoice.client_contract_number.client_number.name 

By the way, sind Ihre Feldnamen verwirrend. client_contract_number ist keine Nummer, es ist ein Vertrag. Und client_number ist auch keine Nummer, es ist ein Client. Rufen Sie sie einfach client_contract und client.

bearbeiten nach Frage Update

Ich bin nicht sicher, was Sie versuchen, hier zu tun. invoices_list ist ein Queryset aller Rechnungen - offensichtlich ist es nicht sinnvoll zu fragen, was der Client-Name für diese Liste ist. Vermutlich, was wollen Sie eigentlich zu tun ist, durchlaufen - wahrscheinlich in der Vorlage - und den Namen für jeden ausdrucken:

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

'client_contract_number' sieht für mich wie eine Nummer aus. 'client_number' funktioniert nicht. –

+0

@Dominic Roger: Es gibt zwei Felder namens 'client_contract_number'. Das Modell "Rechnung" ist ein ForeignKey, das in "Vertrag" ist eine Ganzzahl. –

+0

Ich glaube, ich habe so etwas schon einmal versucht, aber es hat nicht funktioniert. Ich denke, so habe ich es in meinem views.py geschrieben. Was würde ich in meinen Ansichten brauchen? – Shehzad009

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)) 

Sie können nicht den Client-Namen aus einer Liste von Rechnungen erhalten. Gibt es eine bestimmte Rechnung, an der Sie interessiert sind? Wenn Sie eine Rechnung haben, können Sie invoice.client_contract_number.client_number.name tun. Aber Sie können es nicht auf einer Liste tun!

Wenn Sie mehrere Joins durchlaufen möchten, stellen Sie sicher, dass Ihr Abfragesatz eine select_related-Klausel hat.

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

Das stellt sicher, dass nur eine große Abfrage vorne ausgeführt up, anstatt möglicherweise Hunderte, wenn Sie durch eine Liste sind laufen, dann für jedes Objekt eine 3 Beziehung Abfrage zu tun. Jedes Mal, wenn Sie mehr als 1 dot (invoice.client ist ein Punkt) haben, sollten Sie in Erwägung ziehen, select_related zu verwenden.

+0

Grundsätzlich möchte ich eine Tabelle anzeigen, wo in einer Spalte alle Rechnungs-ID angezeigt wird. Es sollte in einer anderen Spalte sein, die alle Kundennamen anzeigt. Die korrekte Rechnungs-ID muss jedoch mit dem korrekten Kundennamen in derselben Zeile übereinstimmen. – Shehzad009

+0

@Sheh Ich verstehe, was Sie versuchen zu tun. Die angenommene Antwort ist richtig. Sie sollten den Clientnamen über die Rechnung erhalten, indem Sie mehrere Beziehungen mithilfe der Punktsyntax aufspannen. Das sollte in der Vorlage gemacht werden. Aus Ihrer Sicht nicht. Wenn Sie über die Rechnungen iterieren, müssen Sie das Clientattribut für diese Rechnungen extrahieren. Mein Rat zu select_related ist immer noch ein guter Ratschlag. Verwenden Sie in Ihrer Ansicht select_related und greifen Sie auf den Clientnamen in der Vorlage zu. –