Reputation: 1607
I have another Django/python question. I have a models.py which look something like this.
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
I know in django if I look for {{invoices.client_contract_number }}
, I get the client contract number. But supposing I wanted to know for a particular invoice, how would I look up the clients name is? I cannot do {{invoice.name}}, because there is no foregin key value for client in invoice.
Edit: Here is my views
@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))
And error.
'QuerySet' object has no attribute 'client_contract_number'
Upvotes: 0
Views: 387
Reputation: 599450
You can follow the relationship across two joins:
invoice.client_contract_number.client_number.name
By the way, your field names are confusing. client_contract_number
isn't a number, it's a Contract. And client_number
isn't a number either, it's a Client. Just call them client_contract
and client
.
Edit after question update
I'm not sure what you're trying to do here. invoices_list
is a queryset of all invoices - obviously it doesn't make sense to ask what the client name is for that list. Presumably what you actually want to do is iterate through - probably in your template - and print out the name for each one:
{% for invoice in invoices_list %}
Client name: {{ client_contract_number.client_number.name }}
{% endfor %}
Upvotes: 2
Reputation: 48710
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))
You can't get the client name from a LIST of invoices. Is there a particular invoice that you're interested in?
When you have an instance of an invoice, then you can do invoice.client_contract_number.client_number.name
. But you can't do it on a list!
By the way, if you're going to be traversing multiple joins, make sure your query set has a select_related
clause.
invoices_list = Invoice.objects.select_related(depth=3).all()
That will ensure that only one big query is executed up front, rather than potentially hundreds if you're iterating through a list, then doing a 3 relation query for each object. Any time you have more than 1 dot
(invoice.client is one dot), strongly consider using select_related.
Upvotes: 0