From 628e2d1f76527f8af31a5630efbce42bda75d1ba Mon Sep 17 00:00:00 2001 From: Toksi86 Date: Mon, 1 Sep 2025 14:21:54 +0500 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=BB=D0=B2=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D1=80=D1=83=D1=87=D0=BA=D0=B0=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=D0=B0=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D0=B5=D0=BA=D1=82=D0=BE=D0=B2=20=D1=83=D1=87=D0=B0=D1=81?= =?UTF-8?q?=D1=82=D0=B2=D1=83=D1=8E=D1=89=D0=B8=D1=85=20=D0=B2=20=D0=BF?= =?UTF-8?q?=D0=B0=D1=80=D1=82=D0=BD=D1=91=D1=80=D1=81=D0=BA=D0=B8=D1=85=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D0=B0=D1=85=20?= =?UTF-8?q?=D1=81=20=D1=83=D1=80=D0=BE=D0=B2=D0=BD=D0=B5=D0=BC=20=D0=B4?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D1=83=D0=BF=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- partner_programs/permissions.py | 26 ++++++++++++++++++++++++++ partner_programs/urls.py | 6 ++++++ partner_programs/views.py | 17 ++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/partner_programs/permissions.py b/partner_programs/permissions.py index b96037df..ec2bc4c7 100644 --- a/partner_programs/permissions.py +++ b/partner_programs/permissions.py @@ -1,6 +1,32 @@ from rest_framework.permissions import BasePermission +from partner_programs.models import PartnerProgram + class IsProjectLeader(BasePermission): def has_object_permission(self, request, view, obj): return obj.project.leader == request.user + + +class IsExpertOrManagerOfProgram(BasePermission): + """ + Доступ разрешён только экспертам и менеджерам конкретной программы. + """ + + def has_permission(self, request, view): + if not request.user or not request.user.is_authenticated: + return False + + program_id = view.kwargs.get("pk") + if not program_id: + return False + + try: + program = PartnerProgram.objects.get(pk=program_id) + except PartnerProgram.DoesNotExist: + return False + + if program.is_manager(request.user): + return True + + return program.experts.filter(user=request.user).exists() diff --git a/partner_programs/urls.py b/partner_programs/urls.py index 3a361024..423d24d5 100644 --- a/partner_programs/urls.py +++ b/partner_programs/urls.py @@ -6,6 +6,7 @@ PartnerProgramDataSchema, PartnerProgramDetail, PartnerProgramList, + PartnerProgramProjectsAPIView, PartnerProgramProjectSubmitView, PartnerProgramRegister, PartnerProgramSetLiked, @@ -44,4 +45,9 @@ ProgramProjectFilterAPIView.as_view(), name="program-projects-filter", ), + path( + "/projects/", + PartnerProgramProjectsAPIView.as_view(), + name="partner-program-projects", + ), ] diff --git a/partner_programs/views.py b/partner_programs/views.py index 993a1c6d..9f981509 100644 --- a/partner_programs/views.py +++ b/partner_programs/views.py @@ -23,7 +23,7 @@ PartnerProgramUserProfile, ) from partner_programs.pagination import PartnerProgramPagination -from partner_programs.permissions import IsProjectLeader +from partner_programs.permissions import IsExpertOrManagerOfProgram, IsProjectLeader from partner_programs.serializers import ( PartnerProgramDataSchemaSerializer, PartnerProgramFieldSerializer, @@ -424,3 +424,18 @@ def post(self, request, pk): projects, many=True, context={"request": request} ) return paginator.get_paginated_response(serializer_out.data) + + +class PartnerProgramProjectsAPIView(generics.ListAPIView): + """ + Список всех проектов участников конкретной партнёрской программы. + Доступ разрешён только менеджерам и экспертам программы. + """ + + serializer_class = ProjectListSerializer + permission_classes = [IsAuthenticated, IsExpertOrManagerOfProgram] + pagination_class = PartnerProgramPagination + + def get_queryset(self): + program = get_object_or_404(PartnerProgram, pk=self.kwargs["pk"]) + return Project.objects.filter(program_links__partner_program=program).distinct()