如何使用django查找员工分数的百分比
How to find the percentage of employee scores using django
我有一个 table 叫做任务。它捕获任务、任务分数和分配给它的员工。
我想使用员工本周的总任务分数(持续时间应该是动态的。最好是输入字段)和分配的总分数来计算员工的绩效。
我正在考虑汇总实际分数,然后除以购买总分,然后乘以 100 得到百分比。我的主要挑战是在哪里执行此计算。我应该创建一个名为性能的模型并使用一个函数吗?或者谁能告诉我该怎么做?
这是模型;
class Task(models.Model):
title = model.CharField(max_length=200)
scores = models.IntegerField(null=True, blank=True)
def __str__(self):
return self.name
这是我要使用的公式。表现(%)=实际得分/总得分*100。总得分应为输入字段。
更新
这是相关的模型。我将用户模型用作员工。
**USER OR EMPLOYEE MODEL**
class User(AbstractUser):
ROLE_CHOICES = (
("STAFF", "Staff"),
("HOD", "Hod"),
("CEO", "Ceo"),
)
GENDER_CHOICES = (
("Male", "Male"),
("Female", "Female")
)
CONFIRMATION_CHOICES = (
("YES", "yes"),
("NO", "no")
)
UNDERTAKING_CHOICES = (
("YES", "yes"),
("NOT YET", "Not yet")
)
GENDER_CHOICES = (
("Male", "Male"),
("Female", "Female")
)
EMPLOYEE_TYPE_CHOICES = (
("Permanent", "Permanent"),
("Contract", "Contract")
)
first_name = models.CharField(max_length=100, blank=True)
last_name = models.CharField(max_length=100, blank=True)
middle_name = models.CharField(max_length=100, null=True, blank=True)
email = models.EmailField(null=True)
avatar = models.ImageField(upload_to='images/avatar', null=True, blank=True)
department = models.ForeignKey(Department, related_name='userdept', on_delete=models.CASCADE, null=True)
role = models.ForeignKey(Role, related_name='userrol', on_delete=models.CASCADE, null=True, blank=True)
user_role = models.CharField(max_length=100, choices=ROLE_CHOICES, null=True)
avatar = models.ImageField(upload_to="avatars", null=True, blank=True)
is_hod = models.BooleanField(default=False)
is_ceo = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
gender = models.CharField(max_length=100, choices=GENDER_CHOICES, null=True, blank=True)
cell_phone = models.CharField(max_length=20, blank=True, null=True)
employee_id = models.CharField(max_length=200, null=True, blank=True)
supervisor = models.CharField(max_length=200, null=True, blank=True)
work_email = models.EmailField(null=True, blank=True)
work_phone = models.CharField(max_length=20, blank=True)
start_date = models.CharField(max_length=20, blank=True)
salary = models.CharField(max_length=20, blank=True, null=True)
work_location = models.CharField(max_length=20, null=True, blank=True)
probation_length = models.CharField(max_length=20, null=True, blank=True)
pay_slip_type = models.CharField(max_length=20, null=True, blank=True)
can_terminate = models.CharField(max_length=20, null=True, blank=True)
dob = models.CharField(max_length=20, null=True, blank=True)
employee_type = models.CharField(max_length=20, choices=EMPLOYEE_TYPE_CHOICES, null=True, blank=True)
comfirmed = models.CharField(max_length=3, choices=CONFIRMATION_CHOICES, null=True)
undertaking = models.CharField(max_length=8, choices=UNDERTAKING_CHOICES, null=True)
leave_days = models.IntegerField(null=True, blank=True)
line_manager = models.CharField(max_length=20, null=True, blank=True)
last_promotion_date = models.CharField(max_length=20, null=True, blank=True)
def __str__(self):
return self.first_name+' '+self.last_name
**TASK MODEL**
from django.db import models
from departments.models import Department
from akps.models import Akp
from users.models import User
from goals.models import OrganisationGoal, OrganisationSubGoal, DepartmentGoal
from django.template.loader import render_to_string
from django.core.mail import send_mail
from django.core.mail import EmailMultiAlternatives
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.text import slugify
# from django.template.loader import render_to_string
from django.core.mail import send_mail
from django.core.mail import EmailMultiAlternatives
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.text import slugify
from django.core.exceptions import ValidationError
class Task(models.Model):
STATUS_CHOICES = (
("COMPLETED", "completed"),
("FAILED", "failed"),
)
department = models.ForeignKey(Department, related_name='soussdepartmentt', on_delete=models.CASCADE, null=True)
akp = models.ForeignKey(Akp, related_name='sousakpp', on_delete=models.CASCADE, null=True)
organisationgoal = models.ForeignKey(OrganisationGoal, on_delete=models.CASCADE, null=True)
organisationsubgoal = models.ForeignKey(OrganisationSubGoal, on_delete=models.CASCADE, null=True, blank=True)
departmentgoal = models.ForeignKey(DepartmentGoal, on_delete=models.CASCADE, related_name='departgoal', null=True, blank=True)
name = models.CharField(max_length=300, null=True)
description = models.TextField(max_length=1000, null=True)
assignedby = models.ForeignKey(User, on_delete=models.CASCADE, related_name='taskassignb', null=True, blank=True)
assignedto = models.ForeignKey(User, on_delete=models.CASCADE, related_name='taskassignt', null=True, blank=True)
user = models.ForeignKey(User, related_name='usertas', on_delete=models.CASCADE, null=True)
scores = models.IntegerField(null=True, blank=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, null=True, blank=True)
email = models.EmailField(null=True)
due_date = models.DateField(null=True)
created_at = models.DateTimeField(auto_now_add=True, null=True)
updated_at = models.DateTimeField(auto_now=True, null=True)
def __str__(self):
return self.name
def clean(self):
other_tasks = Task.objects.exclude(pk=self.pk) \
.filter(departmentgoal=self.departmentgoal)
if other_tasks.count() > 0:
contributed = (
other_tasks.values("departmentgoal")
.annotate(total=models.Sum("scores"))
.values_list("total", flat=True)[0]
)
else:
contributed = 0
if self.scores and self.scores + contributed > self.departmentgoal.scores:
raise ValidationError({"scores": "Score is too much"})
这是一个场景;
用户 A 已完成 10 个每周任务中的 8 个。他一共得了18分。注意:每周得分不能超过20分。
每周重复上述过程。让我们说第二周,他得到了20分。
1个月、4个月、6个月或1年后,我想
计算他的表现并显示在他的仪表板上。数学是实际分数/总分 * 100。我相信这可以通过用户和任务模型来实现,但我不知道如何实现。
用户和仪表板视图
from tasks.models import Task
from users.models import User
from goals.models import DepartmentGoal, OrganisationGoal
from django.utils import timezone
from datetime import timedelta
def dashboard(request):
completed_tasks = Task.objects.filter(status="COMPLETED", assignedto=request.user).count()
failed_tasks = Task.objects.filter(status="FAILED", assignedto=request.user).count()
debt_complt_goal = DepartmentGoal.objects.filter(status="COMPLETED", department=request.user.department).count()
debt_failed_goal = DepartmentGoal.objects.filter(status="FAILED", department=request.user.department).count()
complt_org_goals = OrganisationGoal.objects.filter(status="COMPLETED").count()
failed_org_goals = OrganisationGoal.objects.filter(status="FAILED").count()
return render (request, 'home.html', {
'completed_tasks':completed_tasks,
'failed_tasks':failed_tasks,
'debt_complt_goal':debt_complt_goal,
'debt_failed_goal':debt_failed_goal,
'complt_org_goals':complt_org_goals,
'failed_org_goals':failed_org_goals,
})
from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
from .models import Profile, User
from .forms import ProfileForm, CreateUserForm, UserSetPasswordForm
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages
def list_users_view(request):
department = request.user.department
dept_users = User.objects.filter(department=department)
users = User.objects.all()
context = {
'users':users,
'dept_users':dept_users
}
return render(request, 'users/list-users.html', context)
我无法将其完全映射到您上面的模型,因为您遗漏了用户映射和时间戳等一些内容,但它应该是这样的:
from django.db.models import Count, Sum, F
from datetime import datetime, timedelta
end_date = datetime.now()
start_date = end_date - timedelta(days=7)
performance = Sum(F('scores')) / (Count(F('scores')) * 100)
Task.objects.filter(
employee_id=123,
timestamp__gt=start_date,
timestamp__lte=end_date
).aggregate(
performance=performance
)
这是我解释的标准:
- 任务与使用
assignedto
字段的用户相关联。
- 该任务有一个截止日期,在计算绩效时将根据时间范围参数使用该截止日期。
- 任务完成或失败。
- 如果用户完成任务,用户将获得与任务相关的分数。
解决方案
在您的 User
模型上添加自定义方法来计算性能。该方法将要求 start
和 end
日期参数来计算时间范围之间的性能。
from django.db.models import Sum, Q
class User(AbstractUser):
...
def performance(self, start, end):
actual = Sum("scores", filter=Q(status="completed"))
q = self.taskassignt.filter(
due_date__gte=start,
due_date__lt=end # `end` is excluded from the range
).annotate(actual=actual, total=Sum("scores"))
return (q[0].actual / q[0].total) * 100
请注意,时间范围实现从范围中排除了 end
,因为它使用了 lt
(小于)运算符。
方法的用法是:
from django.utils import timezone
from datetime import timedelta
# user is a `User` instance
user.performance(timezone.now() + timedelta(days=-7), timezone.now())
我有一个 table 叫做任务。它捕获任务、任务分数和分配给它的员工。 我想使用员工本周的总任务分数(持续时间应该是动态的。最好是输入字段)和分配的总分数来计算员工的绩效。 我正在考虑汇总实际分数,然后除以购买总分,然后乘以 100 得到百分比。我的主要挑战是在哪里执行此计算。我应该创建一个名为性能的模型并使用一个函数吗?或者谁能告诉我该怎么做?
这是模型;
class Task(models.Model):
title = model.CharField(max_length=200)
scores = models.IntegerField(null=True, blank=True)
def __str__(self):
return self.name
这是我要使用的公式。表现(%)=实际得分/总得分*100。总得分应为输入字段。
更新 这是相关的模型。我将用户模型用作员工。
**USER OR EMPLOYEE MODEL**
class User(AbstractUser):
ROLE_CHOICES = (
("STAFF", "Staff"),
("HOD", "Hod"),
("CEO", "Ceo"),
)
GENDER_CHOICES = (
("Male", "Male"),
("Female", "Female")
)
CONFIRMATION_CHOICES = (
("YES", "yes"),
("NO", "no")
)
UNDERTAKING_CHOICES = (
("YES", "yes"),
("NOT YET", "Not yet")
)
GENDER_CHOICES = (
("Male", "Male"),
("Female", "Female")
)
EMPLOYEE_TYPE_CHOICES = (
("Permanent", "Permanent"),
("Contract", "Contract")
)
first_name = models.CharField(max_length=100, blank=True)
last_name = models.CharField(max_length=100, blank=True)
middle_name = models.CharField(max_length=100, null=True, blank=True)
email = models.EmailField(null=True)
avatar = models.ImageField(upload_to='images/avatar', null=True, blank=True)
department = models.ForeignKey(Department, related_name='userdept', on_delete=models.CASCADE, null=True)
role = models.ForeignKey(Role, related_name='userrol', on_delete=models.CASCADE, null=True, blank=True)
user_role = models.CharField(max_length=100, choices=ROLE_CHOICES, null=True)
avatar = models.ImageField(upload_to="avatars", null=True, blank=True)
is_hod = models.BooleanField(default=False)
is_ceo = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
gender = models.CharField(max_length=100, choices=GENDER_CHOICES, null=True, blank=True)
cell_phone = models.CharField(max_length=20, blank=True, null=True)
employee_id = models.CharField(max_length=200, null=True, blank=True)
supervisor = models.CharField(max_length=200, null=True, blank=True)
work_email = models.EmailField(null=True, blank=True)
work_phone = models.CharField(max_length=20, blank=True)
start_date = models.CharField(max_length=20, blank=True)
salary = models.CharField(max_length=20, blank=True, null=True)
work_location = models.CharField(max_length=20, null=True, blank=True)
probation_length = models.CharField(max_length=20, null=True, blank=True)
pay_slip_type = models.CharField(max_length=20, null=True, blank=True)
can_terminate = models.CharField(max_length=20, null=True, blank=True)
dob = models.CharField(max_length=20, null=True, blank=True)
employee_type = models.CharField(max_length=20, choices=EMPLOYEE_TYPE_CHOICES, null=True, blank=True)
comfirmed = models.CharField(max_length=3, choices=CONFIRMATION_CHOICES, null=True)
undertaking = models.CharField(max_length=8, choices=UNDERTAKING_CHOICES, null=True)
leave_days = models.IntegerField(null=True, blank=True)
line_manager = models.CharField(max_length=20, null=True, blank=True)
last_promotion_date = models.CharField(max_length=20, null=True, blank=True)
def __str__(self):
return self.first_name+' '+self.last_name
**TASK MODEL**
from django.db import models
from departments.models import Department
from akps.models import Akp
from users.models import User
from goals.models import OrganisationGoal, OrganisationSubGoal, DepartmentGoal
from django.template.loader import render_to_string
from django.core.mail import send_mail
from django.core.mail import EmailMultiAlternatives
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.text import slugify
# from django.template.loader import render_to_string
from django.core.mail import send_mail
from django.core.mail import EmailMultiAlternatives
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.text import slugify
from django.core.exceptions import ValidationError
class Task(models.Model):
STATUS_CHOICES = (
("COMPLETED", "completed"),
("FAILED", "failed"),
)
department = models.ForeignKey(Department, related_name='soussdepartmentt', on_delete=models.CASCADE, null=True)
akp = models.ForeignKey(Akp, related_name='sousakpp', on_delete=models.CASCADE, null=True)
organisationgoal = models.ForeignKey(OrganisationGoal, on_delete=models.CASCADE, null=True)
organisationsubgoal = models.ForeignKey(OrganisationSubGoal, on_delete=models.CASCADE, null=True, blank=True)
departmentgoal = models.ForeignKey(DepartmentGoal, on_delete=models.CASCADE, related_name='departgoal', null=True, blank=True)
name = models.CharField(max_length=300, null=True)
description = models.TextField(max_length=1000, null=True)
assignedby = models.ForeignKey(User, on_delete=models.CASCADE, related_name='taskassignb', null=True, blank=True)
assignedto = models.ForeignKey(User, on_delete=models.CASCADE, related_name='taskassignt', null=True, blank=True)
user = models.ForeignKey(User, related_name='usertas', on_delete=models.CASCADE, null=True)
scores = models.IntegerField(null=True, blank=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, null=True, blank=True)
email = models.EmailField(null=True)
due_date = models.DateField(null=True)
created_at = models.DateTimeField(auto_now_add=True, null=True)
updated_at = models.DateTimeField(auto_now=True, null=True)
def __str__(self):
return self.name
def clean(self):
other_tasks = Task.objects.exclude(pk=self.pk) \
.filter(departmentgoal=self.departmentgoal)
if other_tasks.count() > 0:
contributed = (
other_tasks.values("departmentgoal")
.annotate(total=models.Sum("scores"))
.values_list("total", flat=True)[0]
)
else:
contributed = 0
if self.scores and self.scores + contributed > self.departmentgoal.scores:
raise ValidationError({"scores": "Score is too much"})
这是一个场景;
用户 A 已完成 10 个每周任务中的 8 个。他一共得了18分。注意:每周得分不能超过20分。
每周重复上述过程。让我们说第二周,他得到了20分。
1个月、4个月、6个月或1年后,我想 计算他的表现并显示在他的仪表板上。数学是实际分数/总分 * 100。我相信这可以通过用户和任务模型来实现,但我不知道如何实现。
用户和仪表板视图
from tasks.models import Task
from users.models import User
from goals.models import DepartmentGoal, OrganisationGoal
from django.utils import timezone
from datetime import timedelta
def dashboard(request):
completed_tasks = Task.objects.filter(status="COMPLETED", assignedto=request.user).count()
failed_tasks = Task.objects.filter(status="FAILED", assignedto=request.user).count()
debt_complt_goal = DepartmentGoal.objects.filter(status="COMPLETED", department=request.user.department).count()
debt_failed_goal = DepartmentGoal.objects.filter(status="FAILED", department=request.user.department).count()
complt_org_goals = OrganisationGoal.objects.filter(status="COMPLETED").count()
failed_org_goals = OrganisationGoal.objects.filter(status="FAILED").count()
return render (request, 'home.html', {
'completed_tasks':completed_tasks,
'failed_tasks':failed_tasks,
'debt_complt_goal':debt_complt_goal,
'debt_failed_goal':debt_failed_goal,
'complt_org_goals':complt_org_goals,
'failed_org_goals':failed_org_goals,
})
from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
from .models import Profile, User
from .forms import ProfileForm, CreateUserForm, UserSetPasswordForm
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages
def list_users_view(request):
department = request.user.department
dept_users = User.objects.filter(department=department)
users = User.objects.all()
context = {
'users':users,
'dept_users':dept_users
}
return render(request, 'users/list-users.html', context)
我无法将其完全映射到您上面的模型,因为您遗漏了用户映射和时间戳等一些内容,但它应该是这样的:
from django.db.models import Count, Sum, F
from datetime import datetime, timedelta
end_date = datetime.now()
start_date = end_date - timedelta(days=7)
performance = Sum(F('scores')) / (Count(F('scores')) * 100)
Task.objects.filter(
employee_id=123,
timestamp__gt=start_date,
timestamp__lte=end_date
).aggregate(
performance=performance
)
这是我解释的标准:
- 任务与使用
assignedto
字段的用户相关联。 - 该任务有一个截止日期,在计算绩效时将根据时间范围参数使用该截止日期。
- 任务完成或失败。
- 如果用户完成任务,用户将获得与任务相关的分数。
解决方案
在您的 User
模型上添加自定义方法来计算性能。该方法将要求 start
和 end
日期参数来计算时间范围之间的性能。
from django.db.models import Sum, Q
class User(AbstractUser):
...
def performance(self, start, end):
actual = Sum("scores", filter=Q(status="completed"))
q = self.taskassignt.filter(
due_date__gte=start,
due_date__lt=end # `end` is excluded from the range
).annotate(actual=actual, total=Sum("scores"))
return (q[0].actual / q[0].total) * 100
请注意,时间范围实现从范围中排除了 end
,因为它使用了 lt
(小于)运算符。
方法的用法是:
from django.utils import timezone
from datetime import timedelta
# user is a `User` instance
user.performance(timezone.now() + timedelta(days=-7), timezone.now())