我正在设置两个模型,时间表和时间表条目。 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")
```
答案 0 :(得分:1)
答案既简单又复杂。您可以在模型方法上使用@cached_property
装饰器(例如recalculate
-您可以重命名total_hours
并将其从save
方法中删除),然后缓存cached_property
-仅在每次有新的或编辑的时间条目时使它无效-通过删除cached_property
。 Cached 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 recalculate
和timesheet.recalculate
。两种方式都可以从支持答案中获得帮助。谢谢!
save