Вычислите количество часов, проведенных пользователем за день
У меня есть таблица Clocking в базе данных. Я хочу подсчитать время, проведенное пользователями за день.
Например 2024-03-21
, пользователь 1 тратит 6.8 hours
, на следующий день он тратит n количество часов и так далее (['6.8', 'n', ... 'n']
)
user | date | timein | timeout |
---|---|---|---|
1 | 2024-03-21 | 10:42 AM | 12:00 PM |
1 | 2024-03-21 | 01:10 PM | 06:00 PM |
1 | 2024-03-22 | 01:00 PM | 05:47 PM |
... | ... | ... | ... |
Это мой models.py
class Clocking(models.Model):
user = models.ForeignKey('User', models.DO_NOTHING)
timein = models.CharField(max_length=15, blank=True, null=True)
timeout = models.CharField(max_length=15, blank=True, null=True)
date = models.DateField(null=False)
Я хотел получить список часов, проведенных в день, что было бы очень полезно для меня при построении графиков.
если вы хотите получить время, проведенное пользователем, вы можете выбрать все записи за одну дату, затем суммировать всех пользователей (timein
- timeout
), для этого вы можете преобразовать Charfield
в объект datetime
с помощью встроенной библиотеки, или лучше всего изменить тип поля вашей базы данных на DateTimeField
или TimeField
.
Пожалуйста, не используйте CharField
для отслеживания. Представьте, что человек вводит now
, как это будет работать? Это означает, что вы увеличите количество возможных значений, а также увеличите использование дискового пространства, хотя последнее, вероятно, не так уж и важно.
По сути, есть два варианта: работать с TimeField
s:
from django.conf import settings
class Clocking(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, models.DO_NOTHING)
date = models.DateField()
timein = models.TimeField()
timeout = models.TimeField(null=True)
или работать с двумя DateTimeField
:
from django.conf import settings
class Clocking(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, models.DO_NOTHING)
timein = models.DateTimeField()
timeout = models.DateTimeField(null=True)
Второй вариант имеет три преимущества: (1) он также легко позволяет правильно регистрировать время в те дни, когда происходит переход на летнее время. Хотя оно обычно меняется в воскресенье около 2:00 AM, чтобы свести к минимуму количество проблем с бухгалтерией, все же возможно, что это произойдет, например, если человек работает в другом часовом поясе в это время; (2) оно также позволяет легко иметь несколько Clocking
в одну и ту же дату, без дополнительной бухгалтерии; и (3) наконец, оно также означает, что мы можем иметь Clocking
, который проходит за полночь. Действительно, представьте себе человека, который приходит в 9:00 вечера и уходит в 01:00 утра следующего дня, тогда в старой модели это будет проблематично, потребуется сначала проверить, не наступило ли время окончания раньше времени начала.
С помощью этого мы можем генерировать статистику для даты начала работы с элементом:
# second model
from django.db.models import F, Sum
from django.db.models.functions import TruncDate
Clocking.objects.filter(timeout__isnull=False).values(
date=TruncDate('timein')
).annotate(total=Sum(F('timeout') - F('timein'))).order_by('date')
Note: Specifying
null=False
[Django-doc] is not necessary: fields are by default not NULLable.
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL
[Django-doc] to refer to the user model, than to use theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation.