为什么我收到错误:'QuerySet' 对象没有属性?

Ily*_*bik 2 django django-queryset

我有3个模型

class Lease(CommonInfo):
    version = IntegerVersionField( )
    #amount  = models.DecimalField(max_digits=7, decimal_places=2)
    is_renewed = models.BooleanField(default=False)
    unit = models.ForeignKey(Unit)
    is_terminated = models.BooleanField(default=False)

class LeaseTerm(CommonInfo):
    version = IntegerVersionField( )
    start_period = models.ForeignKey(Period, related_name='start_period' )
    end_period = models.ForeignKey(Period, related_name='end_period')
    lease = models.ForeignKey(Lease)
    increase  = models.DecimalField(max_digits=7, decimal_places=2)
    amount  = models.DecimalField(max_digits=7, decimal_places=2)
    is_terminated = models.BooleanField(default=False)

    def clean(self):
    model = self.__class__
    if self.lease_id and (self.is_terminated == False) and model.objects.filter(lease=self.lease, is_active=True ).count() == 1:
        raise ValidationError('!Lease has a active condition already, Terminate prior to creation of new one'.format(self.lease))

class LeasePayment(CommonInfo):
    version = IntegerVersionField( )
    amount  = models.DecimalField(max_digits=7, decimal_places=2)
    leaseterm = models.ForeignKey(LeaseTerm)
    period_payed_for = models.DateTimeField()
    payment_date = models.DateTimeField()
Run Code Online (Sandbox Code Playgroud)

(clean 方法只允许一个 LeaseTerm 处于活动状态且不被终止。)

在我看来,我希望看到为该 Lease 的活动 LeaseTerm 完成的所有付款

    lease = get_object_or_404(Lease, pk=lease_id)
    leaseterm = LeaseTerm.objects.filter(lease=lease, is_terminated =False, is_active = True )
    payment = leaseterm.leasepayment_set.all().order_by('payment_date')
Run Code Online (Sandbox Code Playgroud)

但出现错误

'QuerySet' 对象没有属性 'leasepayment_set'

我做错了什么?

Leo*_*rd2 5

模型的实例LeaseTerm具有属性leasepayment_set,而不是模型的查询集LeaseTerm。您可以leasepayment_set通过获取这样的实例来访问。

  1. get 代替 filter

    leaseterm = LeaseTerm.objects.get(lease=lease, ...)
    payment = leaseterm.leasepayment_set.all()
    
    Run Code Online (Sandbox Code Playgroud)
  2. 循环查询集

    leaseterm = LeaseTerm.objects.filter(lease=lease, ...)
    for lt in leaseterm: # lt is an instance of LeaseTerm
        payment = lt.leasepayment_set.all()
    
    Run Code Online (Sandbox Code Playgroud)
  3. (通过评论更新,感谢 Alasdair 和 Ingomar)从相关模型开始,它是更高效和优雅的查询表达式。

    LeasePayment.objects.filter(leaseterm__lease=lease)
    
    Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,还有第三个选项可能有用:创建一个 `LeasePayment` 查询集并使用双下划线符号来过滤租赁:`payments = LeasePayment.objects.filter(leaseterm__lease=lease)` (4认同)