正确聚合模型对象和简单视图计算

时间:2013-01-22 17:36:32

标签: django django-views

如果“allotted_pto”(付费休假)是UserProfile模型中的整数字段(表示天数):

class UserProfile(models.Model):  
    user = models.ForeignKey(User, unique=True)
    fullname = models.CharField(max_length=64, unique=False)
    company = models.CharField(max_length=50, choices=CLIENT_CHOICES)
    ...
    allotted_pto = models.IntegerField(max_length=2, blank=True, null=True)
    ...

    User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])

和“total_days”返回休假请求模型中的整数:

class LeaveRequest(models.Model):
    employee = models.ForeignKey(UserProfile)
    supervisor = models.ForeignKey(UserProfile, related_name='+', blank=False, null=False)
    ...
    total_days = models.IntegerField(max_length=2, blank=True, null=True)

    def __unicode__ (self):
            return u'%s %s' % (self.employee, self.submit_date)

    def save(self, *args, **kwargs):
            fromdate = self.start_date
            todate = self.return_date
            daygenerator = (fromdate + timedelta(x + 1) for x in xrange((todate - fromdate).days))
            self.total_days = sum(1 for day in daygenerator if day.weekday() < 5)
            super(LeaveRequest, self).save(*args, **kwargs)
            ...

如何构建一个视图,该视图从过滤器记录集中提取“total_days”的总和,并从用户配置文件中的“allotted_pto”中减去该总和?我写的简单视图(见下文)产生“total_days”对象的数量(以字典形式)而不是计算实际天数,并且“allotted_pto”的请求显然是错误构造的,因为它根本不返回任何内容......

#views.py 

def leave_screen(request, id):
    profile = UserProfile.objects.get(user=id)
    records = LeaveRequest.objects.filter(employee=id)
    agg_pto = LeaveRequest.objects.aggregate(Count('total_days'))
    if profile.allotted_pto: #if the allotted_pto field in UserProfile is not empty
            allotted_pto = profile.allotted_pto
            remaining_pto = allotted_pto - agg_pto
    else:
            remaining_pto = "na"
    return render_to_response("vacation/leave_request.html", {'records': records, 'agg_pto': agg_pto, 'remaining_pto': remaining_pto})

好的,想出了计算:

def leave_screen(request, id):
    ...
    agg_pto = LeaveRequest.objects.filter(employee=id).aggregate(Sum('total_days'))
    agg_pto = agg_pto['total_days__sum']

只需弄清楚如何从用户配置文件模型中提取allotted_pto整数。

1 个答案:

答案 0 :(得分:1)

好的,所以这并不像我想象的那么困难。第一个挑战是获得对象的总和。我的第一次尝试很接近,但我应该使用“Sum”而不是“Count”:

agg_pto = LeaveRequest.objects.filter(employee=id).aggregate(Sum('total_days'))

然后我只使用python方法从字典中提取值:

agg_pto = agg_pto['total_days__sum']

最后:

def leave_screen(request, id):
    user = request.user.id
    profile = request.user.get_profile()
    records = LeaveRequest.objects.filter(employee=id).order_by('-submit_date')
    agg_pto = LeaveRequest.objects.filter(employee=id).aggregate(Sum('total_days'))
    agg_pto = agg_pto['total_days__sum']
    allotted_pto = profile.allotted_pto
    if allotted_pto: #if the allotted_pto field in UserProfile is not empty
            remaining_pto = allotted_pto - agg_pto
    else:
            remaining_pto = "na"
    supervised_records = LeaveRequest.objects.filter(supervisor=id).order_by('-submit_date')
    return render_to_response("vacation/leave_request.html", {'records': records, 'supervised_records': supervised_records, 'agg_pto': agg_pto, 'allotted_pto': allotted_pto, 'remaining_pto': remaining_pto, 'profile': profile })

我不知道为什么我很难找出从UserProfile中提取对象的语法。但我知道django-debug-toolbar非常有用。