【问题标题】:Django question on querysets关于查询集的 Django 问题
【发布时间】:2011-06-03 22:22:03
【问题描述】:

我还有另一个 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'

【问题讨论】:

    标签: django forms views models django-queryset


    【解决方案1】:

    您可以跨两个连接跟踪关系:

    invoice.client_contract_number.client_number.name
    

    顺便说一句,您的字段名称令人困惑。 client_contract_number 不是数字,而是合同。 client_number 也不是一个数字,它是一个客户。打电话给他们client_contractclient

    问题更新后编辑

    我不确定你想在这里做什么。 invoices_list 是所有发票的查询集 - 显然询问该 list 的客户名称是什么是没有意义的。大概你真正想要做的是迭代 - 可能在你的模板中 - 并打印出每个人的名称:

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

    【讨论】:

    • client_contract_number 在我看来就像一个数字。 client_number 没有。
    • @Dominic Roger:有两个字段称为client_contract_numberInvoice 模型中的一个是 ForeignKey,Contract 中的一个是整数。
    • 我想我以前尝试过类似的方法,但没有奏效。我想这就是我在views.py中写它的方式。我的观点需要什么?
    • @Shehzad009:你不需要任何东西,只是我在上面发布的。如果您遇到特定问题,请发布您使用的代码和完整的回溯。
    • 好吧,我想我终于明白了。我希望它可以通过我的代码运行。在我看来,我得到了这样的东西:“invoice_name = invoices_list[0].client_contract_number.client_number.name”。此外,我的模板中也使用了您的打印方法。
    【解决方案2】:
    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。

    【讨论】:

    • 基本上我想显示一个表格,其中一列将显示所有发票 ID。应该在另一列中显示所有客户名称。但是,正确的发票 ID 必须与同一行中的正确客户名称匹配。
    • @Sheh 我明白你想要做什么。接受的答案是正确的。您应该通过使用点语法跨越多个关系来通过发票获取客户名称。这应该在模板中完成。在你看来不是。当您遍历发票时,您需要提取发票客户名称属性。不过,我对 select_related 的建议仍然是很好的建议。在您的视图中使用 select_related,并在模板中访问客户端名称。
    猜你喜欢
    • 1970-01-01
    • 2017-08-09
    • 2010-10-19
    • 2012-12-08
    • 2020-04-20
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多