如何使用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"})

这是一个场景;

用户和仪表板视图

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
)

这是我解释的标准:

  1. 任务与使用 assignedto 字段的用户相关联。
  2. 该任务有一个截止日期,在计算绩效时将根据时间范围参数使用该截止日期。
  3. 任务完成或失败。
  4. 如果用户完成任务,用户将获得与任务相关的分数。

解决方案

在您的 User 模型上添加自定义方法来计算性能。该方法将要求 startend 日期参数来计算时间范围之间的性能。

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())