如何计算我的时间表模型中的总时数?

时间:2019-04-16 11:52:14

标签: python django

我正在设置两个模型,时间表和时间表条目。 TimesheetEntry将是内联的,并在admin.py文件中进行设置,然后您可以在其中放置每个项目的当前时间。我的问题是如何创建函数并计算total_hours,以便可以在Django模板的自定义表中对其进行可视化?

class TimesheetEntry(TimeStampedModel):
    hours = models.DecimalField(max_digits=4, decimal_places=2, default=0, verbose_name=_("Hours"))
    timesheet = models.ForeignKey('timesheet.TimeSheet', verbose_name=_("Timesheet"),
                                  related_name='timesheet_entries', on_delete=models.CASCADE)
    project = models.ForeignKey('project.Project', verbose_name=_("Project"),
                                related_name='timesheet_entries', on_delete=models.PROTECT, null=True)
    project_role = models.ForeignKey('project.ProjectRole', verbose_name=_("Project role"),
                                     related_name='timesheet_entries', on_delete=models.PROTECT, null=True)

    def __str__(self):
        return f"{self.timesheet} - {self.project} - {self.project_role}"

    def save(self, **kwargs):
        self.timesheet.save()
        super().save(**kwargs)

    class Meta:
        verbose_name = _("Timesheet entry")
        verbose_name_plural = _("Timesheet entries")


class Timesheet(TimeStampedModel):
    date = models.DateField(verbose_name=_("Date"), default=datetime.date.today, editable=True)

    total_hours = models.DecimalField(max_digits=4, decimal_places=2, verbose_name=_("Total hours"), editable=False)

    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='timesheet')

    def __str__(self):
        return f"{self.user} - {date_format(self.date, 'DATE_FORMAT')}"

    def recalculate(self):
        self.total_hours = self.timesheet_entries.all().aggregate(total_hours=Sum('hours'))['total_hours'] or 0

    def save(self, **kwargs):
        self.recalculate()
        super().save(**kwargs)

    def projects(self):
        from hr.project.models import Project

        return Project.objects.filter(
            pk__in=self.timesheet_entries.all().values_list('project_id', flat=True).distinct()
        )

    class Meta:
        verbose_name = _("Timesheet")
        verbose_name_plural = _("Timesheets")
    ```

3 个答案:

答案 0 :(得分:1)

答案既简单又复杂。您可以在模型方法上使用@cached_property装饰器(例如recalculate-您可以重命名total_hours并将其从save方法中删除),然后缓存cached_property-仅在每次有新的或编辑的时间条目时使它无效-通过删除cached_propertyCached Property

class Timesheet(TimeStampedModel):
    date = models.DateField(verbose_name=_("Date"), default=datetime.date.today, editable=True)

    total_hours = models.DecimalField(max_digits=4, decimal_places=2, verbose_name=_("Total hours"), editable=False)

    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='timesheet')

    def __str__(self):
        return f"{self.user} - {date_format(self.date, 'DATE_FORMAT')}"

    @cached_property
    def total_hours(self):
       return self.timesheet_entries.all().aggregate(total_hours=Sum('hours'))['total_hours'] or 0

    def save(self, **kwargs):

        super().save(**kwargs)

答案 1 :(得分:1)

聚集不是您要在此处使用的,因为您正在对实例进行汇总。所以应该这样做:

REM ************************ Determine input file count ************************
SET "target=TXT"
CD /D "%binpath%"

FOR %%A IN (logpath,ftp_log)DO IF NOT DEFINED %%A GOTO END

FOR %%A IN ("inputfilelist.txt","unix_ftp.config","%logpath%"
)DO IF NOT EXIST "%%~A" GOTO END

FOR /F %%A IN ('FIND /C "%target%"^<"inputfilelist.txt"'
)DO IF "%%A"=="0" GOTO END

:PROCEED
REM *** Dynamically create the ftp get commands file, and download the files ***
COPY /Y "unix_ftp.config" "unixftp_get1.txt"

(   FOR /F "DELIMS=" %%A IN ("inputfilelist.txt")DO ECHO get %%A
    ECHO bye
)>>"unixftp_get1.txt"

ftp -v -s:"unixftp_get1.txt" %server% >>"%logpath%%ftp_log%"

然后,您可以将此属性设置为一个属性(如Icognos所指出),或者您覆盖save函数并在save函数中调用recalculate。

答案 2 :(得分:0)

在进行编辑后,时间表模型中的agent.Completion = date(); // Agent received date set earlier in Source action checkForRuleBreaks(agent.ReceivedDate, agent.Completion); 可以正常工作。真正的问题是我需要在Timesheet Serializer中回调,并且必须在其中调用函数def recalculatetimesheet.recalculate。两种方式都可以从支持答案中获得帮助。谢谢!

save