Начинающий Django: Как сделать запрос в ORM Django для расчета полей на основе дат - PullRequest
0 голосов
/ 28 декабря 2010

Задача: Запрос модели в Django ORM, чтобы я мог вычислять поля на основе дат.В частности, извлеките месяцы из поля model.date и вычислите значения на основе этих месяцев.

Пример модели:

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 - это юникод, и я почему-то не могу его скрытьв целое число ...):

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 %}  

Что я сделал в представлениях.py не выглядит очень элегантно, есть ли лучший способ вытащить диапазоны дат, как годы, месяцы или дни из полей даты?И в стороне, как мне получить entry.rate целым числом, которое я могу вычислить?

Спасибо за ваш вклад!(да, я очень новичок в программировании, Python и Django ... мне потребовалась неделя, чтобы написать это): -)

Ответы [ 2 ]

1 голос
/ 09 января 2011

Вот решение, которое я в конечном итоге разработал с помощью вышеупомянутых входных данных и других сообщений 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])
0 голосов
/ 30 декабря 2010

Мне кажется, что твой диапазон дат подходит.entry.rate является внешним ключом для модели PersonIncome.Не имеет смысла умножать часы на pk экземпляра PersonIncome.

Я бы добавил поле тарифа для Person:

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

Тогда вы можете сделать это в представлении:

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

Принимая во внимание, что это предполагает, что у Человека всегда одинаковый показатель для любой выполняемой работы.НТН

...