|
1 | 1 | from django.shortcuts import get_object_or_404
|
2 | 2 | from django_filters.rest_framework import DjangoFilterBackend
|
| 3 | +from pydantic import ValidationError |
3 | 4 | from rest_framework import filters, generics, status
|
4 | 5 | from rest_framework.permissions import IsAuthenticated
|
5 | 6 | from rest_framework.views import APIView, Response
|
6 | 7 |
|
| 8 | +from examples.assignment.strategies import StrategyName, create_assignment_strategy |
| 9 | +from examples.assignment.workload import WorkloadAllocation |
7 | 10 | from examples.models import Assignment
|
8 | 11 | from examples.serializers import AssignmentSerializer
|
9 |
| -from projects.models import Project |
| 12 | +from projects.models import Member, Project |
10 | 13 | from projects.permissions import IsProjectAdmin, IsProjectStaffAndReadOnly
|
11 | 14 |
|
12 | 15 |
|
@@ -46,3 +49,50 @@ def project(self):
|
46 | 49 | def delete(self, *args, **kwargs):
|
47 | 50 | Assignment.objects.filter(project=self.project).delete()
|
48 | 51 | return Response(status=status.HTTP_204_NO_CONTENT)
|
| 52 | + |
| 53 | + |
| 54 | +class BulkAssignment(APIView): |
| 55 | + serializer_class = AssignmentSerializer |
| 56 | + permission_classes = [IsAuthenticated & IsProjectAdmin] |
| 57 | + |
| 58 | + def post(self, *args, **kwargs): |
| 59 | + try: |
| 60 | + strategy_name = StrategyName[self.request.data["strategy_name"]] |
| 61 | + except KeyError: |
| 62 | + return Response( |
| 63 | + {"detail": "Invalid strategy name"}, |
| 64 | + status=status.HTTP_400_BAD_REQUEST, |
| 65 | + ) |
| 66 | + |
| 67 | + try: |
| 68 | + workload_allocation = WorkloadAllocation(workloads=self.request.data["workloads"]) |
| 69 | + except ValidationError as e: |
| 70 | + return Response( |
| 71 | + {"detail": e.errors()}, |
| 72 | + status=status.HTTP_400_BAD_REQUEST, |
| 73 | + ) |
| 74 | + |
| 75 | + project = get_object_or_404(Project, pk=self.kwargs["project_id"]) |
| 76 | + members = Member.objects.filter(project=project, pk__in=workload_allocation.member_ids) |
| 77 | + if len(members) != len(workload_allocation.member_ids): |
| 78 | + return Response( |
| 79 | + {"detail": "Invalid member ids"}, |
| 80 | + status=status.HTTP_400_BAD_REQUEST, |
| 81 | + ) |
| 82 | + # Sort members by workload_allocation.member_ids |
| 83 | + members = sorted(members, key=lambda m: workload_allocation.member_ids.index(m.id)) |
| 84 | + |
| 85 | + dataset_size = project.examples.count() # Todo: unassigned examples |
| 86 | + strategy = create_assignment_strategy(strategy_name, dataset_size, workload_allocation.weights) |
| 87 | + assignments = strategy.assign() |
| 88 | + example_ids = project.examples.values_list("pk", flat=True) |
| 89 | + assignments = [ |
| 90 | + Assignment( |
| 91 | + project=project, |
| 92 | + example=example_ids[assignment.example], |
| 93 | + assignee=members[assignment.user].user, |
| 94 | + ) |
| 95 | + for assignment in assignments |
| 96 | + ] |
| 97 | + Assignment.objects.bulk_create(assignments) |
| 98 | + return Response(status=status.HTTP_201_CREATED) |
0 commit comments