Django beginner: How to query in django ORM to calculate fields based on dates

依然范特西╮ 提交于 2019-12-12 06:11:18

问题


Task: Querying a model in Django ORM so that I can calculate fields based on dates. Specifically, extract months from a model.datefield and calculate values based on these months.

Example model:

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.'))  

In my views.py, I can extract the months and hours worked per month like this (I use a range because I couldn't figure out how to query for month in months in ORM). And I can calculate the cost of the hours worked by the different people who worked on the project by looping through the entries in each month (just doesn't work right now because entry.rate is a unicode and I somehow can't covert it to an integer...):

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])

Just to complete this example, I loop through the entries in my templates like this:

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

What I have done in views.py doesn't seem very elegant, is there a better way to pull date ranges like years, months or days from datefields? And on the sidelines, how do I get entry.rate to be an integer I can calculate?

Thanks for your input! (yes, I am very new to coding, python, and django... took me a week to write this up) :-)


回答1:


Your date range pulling seems fine for me. entry.rate is a foreign key to the model PersonIncome. Would make no sense to multiply the hours with the pk of the PersonIncome instance.

I would add the rate field to the Person:

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

Then you can do this in the view:

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

Whereas this assumes that a Person has always the same rate for any kind of work done. HTH




回答2:


Here's the solution that I ultimately developed with the above input and other stackoverflow posts.

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])


来源:https://stackoverflow.com/questions/4548638/django-beginner-how-to-query-in-django-orm-to-calculate-fields-based-on-dates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!