Django初学者:如何在django ORM中查询根据日期计算字段

时间:2010-12-28 19:01:51

标签: django django-models django-views

任务:在Django ORM中查询模型,以便我可以根据日期计算字段。 具体而言,从model.datefield中提取月份,并根据这些月份计算值。

示例模型:

class PersonProjectHours(models.Model):  
    project = models.ForeignKey('projects.Project')  
    person = models.ForeignKey('projects.Person')  
    rate = models.ForeignKey('PersonIncome')  
    work_date = models.DateField(help_text=_('Enter date'))  
    hours = models.IntegerField(help_text=_('Enter hours worked on this day.'))  


class PersonIncome(models.Model):  
    person = models.ForeignKey('projects.Person')  
    income = models.DecimalField(help_text=_('Enter new income'), max_digits=10, decimal_places=2)  
    validdate = models.DateField(help_text=_('Enter date from which new income is valid.'))  

在我的views.py中,我可以像这样提取每月工作的月份和小时数(我使用范围因为我无法弄清楚如何在ORM中查询月份)。我可以通过循环每个月的条目来计算从事该项目工作的不同人员的工作时间的成本(因为entry.rate是一个unicode,因此我无论如何都无法将其转换为unicode到整数......):

for month in range(1, 13):
    entries_per_month = PersonProjectHours.objects.filter(work_date__month=month)
    hours = entries_per_month.aggregate(value=Sum('hours'))
    cost = 0
    for entry in entries_per_month:
        cost = cost + (entry.hours * entry.rate)
    work_per_year.append([month,hours,cost])

为了完成这个例子,我循环遍历模板中的条目,如下所示:

{% for month, hours, cost in work_per_year %}  
<tr>  
<td>{{ month }}</td>  
<td>{{ hours.value }}</td>  
<td>{{ cost }}</td>  
</tr>  
{% endfor %}  

我在views.py中所做的事情似乎并不优雅,是否有更好的方法从日期字段中提取日期范围,如年,月或日?在场外,如何将entry.rate作为我可以计算的整数?

感谢您的投入! (是的,我是编码,python和django的新手......花了一个星期的时间来写这篇文章): - )

2 个答案:

答案 0 :(得分:1)

这是我最终使用上述输入和其他stackoverflow帖子开发的解决方案。

project = get_object_or_404(Project, code=pcode)
project_entries = PersonProjectHours.objects.filter(project=project)
project_years = project_entries.dates('work_date', 'year', order='DESC')

month_dict = {}
year_list = []


for year in project_years:
    year_hours=0
    year_costs=0

    year = int(year.strftime("%Y"))

    for month in range(1,13):
        month_entries = project_entries.filter(work_date__year=year).filter(work_date__month=month)
        hours=0
        costs=0
        for entry in month_entries:
            hours = hours + entry.hours
            costs = int(costs + (entry.hours * entry.rate.income))
        year_hours= year_hours + hours
        year_costs= year_costs + costs

        try:
            month_dict[year].append([datetime(year,month,1), hours, costs])
        except KeyError:
            month_dict[year] = ([[datetime(year,month,1), hours, costs]])
    year_list.append([year,year_hours,year_costs])

答案 1 :(得分:0)

你的日期范围对我来说似乎很好。 entry.rate是模型PersonIncome的外键。将小时乘以PersonIncome实例的pk是没有意义的。

我会将费率字段添加到Person:

class Person(models.Model):  
    name = models.CharField(max_length=100)  
    rate = models.IntegerField(max_length=4)  

然后你可以在视图中执行此操作:

cost = cost + (entry.hours * entry.person.rate)

然而,这假定一个人对任何类型的工作总是具有相同的比率。 HTH