Джанго вопрос по наборам запросов - PullRequest
0 голосов
/ 05 января 2011

У меня есть еще один вопрос по Django / python. У меня есть models.py, который выглядит примерно так.

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 для клиента.

Edit: Вот мои взгляды

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

2 голосов
/ 05 января 2011

Вы можете следить за отношениями между двумя объединениями:

invoice.client_contract_number.client_number.name

Кстати, ваши имена полей сбивают с толку.client_contract_number это не число, это контракт.И client_number тоже не число, это Клиент.Просто позвоните им client_contract и client.

Изменить после обновления вопроса

Я не уверен, что вы пытаетесь сделать здесь.invoices_list - это набор запросов для всех счетов - очевидно, не имеет смысла спрашивать, какое имя клиента для этого списка .Предположительно, что вы действительно хотите сделать, это перебрать - возможно, в вашем шаблоне - и распечатать имя для каждого:

{% for invoice in invoices_list %}
    Client name: {{ client_contract_number.client_number.name }}
{% endfor %}
0 голосов
/ 05 января 2011
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.

...