feat: add create_subtasks function to create subtasks when creating a task
This commit is contained in:
parent
7c9cff0802
commit
d61256610d
3 changed files with 30 additions and 27 deletions
|
|
@ -27,16 +27,17 @@ class Task(models.Model):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
class SubTask(models.Model):
|
class SubTask(models.Model):
|
||||||
task = models.ForeignKey(Task, related_name="subtasks", on_delete=models.CASCADE)
|
id = models.CharField(primary_key=True, default=generate_uuid_without_dashes, max_length=32, editable=False, unique=True)
|
||||||
|
task = models.ForeignKey(Task, related_name="subtasks_task", on_delete=models.CASCADE)
|
||||||
title = models.CharField(max_length=255)
|
title = models.CharField(max_length=255)
|
||||||
done = models.BooleanField(default=False)
|
status = models.BooleanField(default=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.task.title} - {self.title}"
|
return f"{self.task.title} - {self.title}"
|
||||||
|
|
||||||
class AssignedTask(models.Model):
|
class AssignedTask(models.Model):
|
||||||
user_id = models.ForeignKey(User, related_name="assigned_tasks", on_delete=models.CASCADE)
|
user_id = models.ForeignKey(User, related_name="assigned_task", on_delete=models.CASCADE)
|
||||||
task = models.ForeignKey(Task, related_name="assigned_tasks", on_delete=models.CASCADE)
|
task = models.ForeignKey(Task, related_name="assigned_task", on_delete=models.CASCADE)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.user_id} - {self.task}"
|
return f"{self.user_id} - {self.task}"
|
||||||
|
|
@ -6,7 +6,7 @@ from .models import Task, SubTask, AssignedTask
|
||||||
class SubTaskSerializer(serializers.ModelSerializer):
|
class SubTaskSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SubTask
|
model = SubTask
|
||||||
fields = ['title', 'done']
|
fields = ['id', 'title', 'status']
|
||||||
|
|
||||||
class AssignedTaskSerializer(serializers.ModelSerializer):
|
class AssignedTaskSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
@ -15,10 +15,10 @@ class AssignedTaskSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class TaskSerializer(serializers.ModelSerializer):
|
class TaskSerializer(serializers.ModelSerializer):
|
||||||
assignees = serializers.SerializerMethodField()
|
assignees = serializers.SerializerMethodField()
|
||||||
subtasks = SubTaskSerializer(many=True, read_only=True)
|
subtasks = SubTaskSerializer(many=True, read_only=True, source="subtasks_task")
|
||||||
|
|
||||||
def get_assignees(self, obj):
|
def get_assignees(self, obj):
|
||||||
return obj.assigned_tasks.all().values('user_id')
|
return obj.assigned_task.all().values('user_id')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Task
|
model = Task
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ from rest_framework.exceptions import APIException
|
||||||
|
|
||||||
class TaskViewSet(viewsets.ModelViewSet):
|
class TaskViewSet(viewsets.ModelViewSet):
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
queryset = Task.objects.all()
|
queryset = Task.objects.all()
|
||||||
serializer_class = TaskSerializer
|
serializer_class = TaskSerializer
|
||||||
|
|
||||||
|
|
@ -31,9 +30,17 @@ class TaskViewSet(viewsets.ModelViewSet):
|
||||||
|
|
||||||
task = serializer.save()
|
task = serializer.save()
|
||||||
self._assign_users_to_task(request.data.get('assigned', []), task)
|
self._assign_users_to_task(request.data.get('assigned', []), task)
|
||||||
self._create_subtasks(request.data.get('subtasks', []), task)
|
|
||||||
|
subtasks = [
|
||||||
|
{"title": title, "status": status}
|
||||||
|
for title, status in zip(request.data.get("subtasks_title", []), request.data.get("subtasks_status", []))
|
||||||
|
]
|
||||||
|
|
||||||
|
if subtasks:
|
||||||
|
self._create_subtasks(subtasks, task)
|
||||||
|
|
||||||
cache.delete(f"task_{task.id}")
|
cache.delete(f"task_{task.id}")
|
||||||
|
|
||||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||||
|
|
||||||
def destroy(self, request, pk=None):
|
def destroy(self, request, pk=None):
|
||||||
|
|
@ -45,12 +52,21 @@ class TaskViewSet(viewsets.ModelViewSet):
|
||||||
except Task.DoesNotExist:
|
except Task.DoesNotExist:
|
||||||
return Response({'error': 'Task not found.'}, status=status.HTTP_404_NOT_FOUND)
|
return Response({'error': 'Task not found.'}, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
|
def _create_subtasks(self, subtask_data, parent_task):
|
||||||
|
if subtask_data:
|
||||||
|
subtasks = [
|
||||||
|
SubTask(title=sub['title'], status=sub['status'], task=parent_task)
|
||||||
|
for sub in subtask_data
|
||||||
|
]
|
||||||
|
SubTask.objects.bulk_create(subtasks)
|
||||||
|
|
||||||
def _assign_users_to_task(self, user_ids, task):
|
def _assign_users_to_task(self, user_ids, task):
|
||||||
users = User.objects.filter(id__in=user_ids)
|
users = User.objects.filter(id__in=user_ids)
|
||||||
missing_users = set(user_ids) - set(users.values_list('id', flat=True))
|
missing_users = set(user_ids) - set(users.values_list('id', flat=True))
|
||||||
|
|
||||||
if missing_users:
|
if missing_users:
|
||||||
raise APIException(f"Users not found: {', '.join(missing_users)}")
|
missing_users_list = list(map(str, missing_users))
|
||||||
|
raise APIException(f"Users not found: {', '.join(missing_users_list)}")
|
||||||
|
|
||||||
AssignedTask.objects.bulk_create(
|
AssignedTask.objects.bulk_create(
|
||||||
[AssignedTask(user_id=user, task=task) for user in users]
|
[AssignedTask(user_id=user, task=task) for user in users]
|
||||||
|
|
@ -69,30 +85,16 @@ class TaskViewSet(viewsets.ModelViewSet):
|
||||||
return Response({'error': f'Invalid status. Valid statuses: {valid_statuses}'}, status=status.HTTP_400_BAD_REQUEST)
|
return Response({'error': f'Invalid status. Valid statuses: {valid_statuses}'}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
cache.delete(f"task_{task.id}")
|
cache.delete(f"task_{task.id}")
|
||||||
|
|
||||||
task.status = new_status
|
task.status = new_status
|
||||||
task.save()
|
task.save()
|
||||||
return Response({'status': 'Status updated.'})
|
return Response({'status': 'Status updated.'})
|
||||||
|
|
||||||
class SubTaskViewSet(viewsets.ModelViewSet):
|
class SubTaskViewSet(viewsets.ModelViewSet):
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
queryset = SubTask.objects.all()
|
queryset = SubTask.objects.all()
|
||||||
serializer_class = SubTaskSerializer
|
serializer_class = SubTaskSerializer
|
||||||
|
|
||||||
|
|
||||||
class AssignedTaskViewSet(viewsets.ModelViewSet):
|
class AssignedTaskViewSet(viewsets.ModelViewSet):
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
queryset = AssignedTask.objects.all()
|
queryset = AssignedTask.objects.all()
|
||||||
serializer_class = AssignedTaskSerializer
|
serializer_class = AssignedTaskSerializer
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
|
||||||
serializer = self.get_serializer(data=request.data)
|
|
||||||
if serializer.is_valid():
|
|
||||||
assigned_task = serializer.save()
|
|
||||||
cache.delete(f"task_{assigned_task.task.id}")
|
|
||||||
|
|
||||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
|
||||||
|
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue