Skip to content

Commit

Permalink
Merge pull request #152 from Pet-projects-CodePET/feature/draft-create
Browse files Browse the repository at this point in the history
[+] Draft creation. R: Project requirements. FB: Added the process of…
  • Loading branch information
ArtemKAF authored Apr 1, 2024
2 parents 3b5cbc3 + 309b11d commit d0e9393
Show file tree
Hide file tree
Showing 10 changed files with 273 additions and 199 deletions.
93 changes: 93 additions & 0 deletions src/backend/api/v1/projects/mixins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from datetime import date
from typing import Any, Dict

from django.db import transaction
from rest_framework import serializers

from apps.projects.models import Project, ProjectSpecialist


class RecruitmentStatusMixin:
def calculate_recruitment_status(self, obj):
"""Метод определения статуса набора в проект."""

if any(
specialist.is_required
for specialist in obj.project_specialists.all()
):
return "Набор открыт"
return "Набор закрыт"


class ProjectOrDraftValidateMixin:
"""Миксин валидации данных проекта или его черновика."""

def _validate_date(self, value, field_name) -> date:
"""Метод валидации даты."""

if value < date.today():
raise serializers.ValidationError(
f"Дата {field_name} не может быть в прошлом."
)
return value

def validate_started(self, value) -> date:
"""Метод валидации даты начала проекта."""

return self._validate_date(value, "начала проекта")

def validate_ended(self, value) -> date:
"""Метод валидации даты завершения проекта."""

return self._validate_date(value, "завершения проекта")

def validate(self, attrs) -> Dict[str, Any]:
"""Метод валидации данных проекта или черновика."""

errors: Dict = {}

queryset = Project.objects.filter(
name=attrs.get("name"),
creator=self.context.get("request").user, # type: ignore
)

if queryset.exists():
errors.setdefault("unique", []).append(
"У вас уже есть проект или его черновик с таким названием."
)
started = attrs.get("started")
ended = attrs.get("ended")
if (started and ended) is not None and started > ended:
errors.setdefault("invalid_dates", []).append(
"Дата завершения проекта не может быть раньше даты начала."
)

if errors:
raise serializers.ValidationError(errors)
return attrs


class ProjectOrDraftCreateMixin:
"""Миксин создания проекта или его черновика."""

def create(self, validated_data) -> Project:
"""Метод создания проекта или его черновика."""

directions = validated_data.pop("directions", None)
project_specialists = validated_data.pop("project_specialists", None)
with transaction.atomic():
project_instance, _ = Project.objects.get_or_create(
**validated_data
)
if directions is not None:
project_instance.directions.set(directions)
if project_specialists is not None:
for project_specialist_data in project_specialists:
skills_data = project_specialist_data.pop("skills")
project_specialist_instance = (
ProjectSpecialist.objects.create(
project=project_instance, **project_specialist_data
)
)
project_specialist_instance.skills.set(skills_data)
return project_instance
13 changes: 13 additions & 0 deletions src/backend/api/v1/projects/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from rest_framework.permissions import SAFE_METHODS, IsAuthenticated


class IsCreatorOrOwnerOrReadOnly(IsAuthenticated):
"""
Класс прав доступа чтение - авторизованным пользователям,
редактирование - только создателю или владельцу объекта."""

def has_object_permission(self, request, view, obj):
return bool(
request.method in SAFE_METHODS
and (request.user == (obj.owner or obj.creator))
)
Loading

0 comments on commit d0e9393

Please sign in to comment.