关于查询集的Django问题

时间:2011-01-05 10:24:51

标签: django forms views models django-queryset

我有另一个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}},因为发票中的客户端没有外包密钥值。

编辑: 这是我的观点

@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 个答案:

答案 0 :(得分: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 %}

答案 1 :(得分: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个关系查询。如果您有多个dot(invoice.client是一个点),请强烈考虑使用select_related。