在django中计算列表理解结果总数的最佳方法

时间:2017-05-13 12:21:07

标签: django list-comprehension

我在我的视图中有一个列表理解,因为我必须根据模型计算字段进行过滤。

leaseterms = LeaseTerm.objects.filter( is_active = True )
tobe_payed_terms = [obj for obj in leaseterms if obj.current_balance < 0]

我用它来显示报告中的所有字段。

目前我必须添加一个仪表板,我只想显示此列表理解的总单位数。

最明智的表现方式是什么?

(我的仪表板中可能会出现这样的情况)

模型 - 我在DEV上使用SQLlite,在PROD和TEST上使用POSTGRES

    class LeaseTerm(CommonInfo):
        version = IntegerVersionField( )
        start_period = models.ForeignKey(Period, related_name='start_period',on_delete=models.PROTECT)
        end_period = models.ForeignKey(Period, related_name='end_period',on_delete=models.PROTECT)
        lease = models.ForeignKey(Lease,on_delete=models.PROTECT)
        increase  = models.DecimalField(max_digits=7, decimal_places=2)
        amount  = models.DecimalField(max_digits=7, decimal_places=2)
        is_renewed = models.BooleanField(default=False)
        is_renewal_letter = models.BooleanField(default=False)
        renewal_letter_date = models.DateField(null=True, blank=True)


        _current_period  = None
        _total_current = None
        _total_payment = None
        _total_current_payment = None
        _total_discount = None
        _total_current_discount = None
        _current_tobe_payed = None
        _current_balance = None
        _is_current_term = None
        _tenant = None




        def _get_total(self):
            from payment.models import LeasePayment
            from conditions.models import LeaseDiscount



            total_payment_dict = LeasePayment.objects.filter(leaseterm_id=self.id, is_active = True ).aggregate(Sum('amount'))



            if total_payment_dict ['amount__sum']:
                total_payment =  total_payment_dict['amount__sum'] 
            else:  
                total_payment =  0

            total_discount_dict = LeaseDiscount.objects.filter(leaseterm_id=self.id, is_active = True ).aggregate(Sum('amount'))


            if total_discount_dict ['amount__sum']:
                total_discount =  total_discount_dict['amount__sum'] 
            else:  
                total_discount =  0



            current_date=datetime.datetime.now().date()
            current_period_dict = Period.objects.filter(start_date__lte=current_date,end_date__gte=current_date, is_active = True ).aggregate(Max('order_value'))


            if current_period_dict['order_value__max']:
                current_period =  current_period_dict['order_value__max'] 
            else:  
                current_period =  0

            tenant = LeaseTenant.objects.filter(lease=self.lease, is_financially_accountable=True ).last()


            if  (self.start_period.order_value <= current_period  <= self.end_period.order_value) and (self.is_active == True):

                is_current_term_dict =  True

            else:  
                is_current_term_dict =  False
                current_period = self.end_period.order_value


            current_discount_dict = LeaseDiscount.objects.filter(leaseterm_id=self.id, 
                is_active = True, period_date__gte=self.start_period,
                 period_date__lte=current_period).aggregate(Sum('amount'))

            if current_discount_dict ['amount__sum']:
                current_discount =  current_discount_dict['amount__sum'] 
            else:  
                current_discount =  0



            current_periods_number = current_period - self.start_period.order_value + 1

            current_tobe_payed =  current_periods_number * self.amount -  current_discount

            current_balance =  total_payment - current_tobe_payed





            self._current_period = current_period
            self._total_payment = total_payment
            self._total_discount = total_discount
            self._current_tobe_payed  = current_tobe_payed 
            self._current_balance = current_balance
            self._is_current_term = is_current_term_dict

            if tenant is not None:
                self._tenant = tenant.tenant
            else:
                self._tenant = None


        @property
        def is_current_term(self):
            if self._is_current_term is None:
                self._get_total()
            return self._is_current_term 

        @property
        def tenant(self):
            if self._tenant is None:
                self._get_total()
            return self._tenant    

        @property
        def current_tobe_payed(self):
            if self._current_tobe_payed is None:
                self._get_total()
            return self._current_tobe_payed


        @property
        def current_balance(self):
            if self._current_balance is None:
                self._get_total()
            return self._current_balance

        @property
        def current_period(self):
            if self._current_period is None:
                self._get_total()
            return self._current_period   

        @property
        def total_payment(self):
            if self._total_payment is None:
                self._get_total()
            return self._total_payment

        @property
        def total_discount(self):
            if self._total_discount is None:
                self._get_total()
            return self._total_discount


        def save(self, *args, **kwargs):
            self.full_clean()
            return super(LeaseTerm, self).save(*args, **kwargs)

        def __unicode__(self):
            return u' %i %s %s ' % (self.id, self.start_period, self.end_period)




    @with_author
    class Period(CommonInfo):
        version = IntegerVersionField( )
        order_value = models.PositiveSmallIntegerField()
        start_date = models.DateField()
        end_date = models.DateField()
        name = models.CharField(max_length=30)
        duration = models.PositiveSmallIntegerField(null=True, blank=True)
        is_special = models.BooleanField(default=False)
        is_marked = models.BooleanField(default=False)
        _is_current = models.NullBooleanField( blank=True, null=True, default=None)
        #not_terminated_active_objects = NotTerminatedActiveManager() 
        def __unicode__(self):
            return u'%s %i %s ' % ("#", self.order_value, self.name)



class Lease(CommonInfo):
    version = IntegerVersionField( )

    unit = models.ForeignKey(Unit,on_delete=models.PROTECT)
    is_terminated = models.BooleanField(default=False)



    _total = None
    _total_current = None

    _total_payment = None
    _total_current_payment = None

    _total_discount = None
    _total_current_discount = None



    def _get_total(self):
        from payment.models import LeasePayment
        from conditions.models import LeaseDiscount



        total_payment_dict = LeasePayment.objects.filter(lease_id=self.id, is_active = True ).aggregate(Sum('amount'))


        if total_payment_dict ['amount__sum']:
            total_payment =  total_payment_dict['amount__sum'] 
        else:  
            total_payment =  0

        total_discount_dict = LeaseDiscount.objects.filter(leaseterm__lease_id=self.id, is_active = True ).aggregate(Sum('amount'))

        if total_discount_dict ['amount__sum']:
            total_discount =  total_discount_dict['amount__sum'] 
        else:  
            total_discount =  0







        self._total_payment = total_payment
        self._total_discount = total_discount
        self._total = total_payment + total_discount



    @property
    def total_payment(self):
        if self._total_payment is None:
            self._get_total()
        return self._total_payment

    @property
    def total_discount(self):
        if self._total_discount is None:
            self._get_total()
        return self._total_discount

    @property
    def total(self):
        if self._total is None:
            self._get_total()
        return self._total


    def __unicode__(self):
        return u'%s %i %s ' % ("lease#", self.id, self.unit)

    def clean(self):
        model = self.__class__
        if self.unit and (self.is_active == True)  and model.objects.filter(unit=self.unit, is_terminated = False , is_active = True).exclude(id=self.id).count() > 0:
            raise ValidationError('Unit has active lease already, Terminate existing one prior to creation of new one or create a not active lease '.format(self.unit))




    def save(self, *args, **kwargs):
        self.full_clean()
        return super(Lease, self).save(*args, **kwargs)


class CommonInfo(models.Model):
    created = models.DateTimeField("creation date", auto_now_add=True)
    modified = models.DateTimeField("modification date", auto_now=True)
    description = models.TextField(null=True, blank=True)
    is_active = models.BooleanField(default=True)


    class Meta:
        abstract = True

1 个答案:

答案 0 :(得分:0)

到目前为止我的解决方案:

leaseterms = LeaseTerm.objects.filter(is_active = True)     negative_balance_term = [obj.urrent_balance&lt;对象中的obj.id用于obj。 0]     count_negative_balance_term = LeaseTerm.objects.filter(id__in = negative_balance_term).count()