Ilo/apps/announcements/api/views.py
2026-05-02 20:01:30 +03:30

85 lines
3.3 KiB
Python

from django.shortcuts import get_object_or_404
from drf_spectacular.utils import OpenApiResponse, extend_schema
from rest_framework import viewsets
from rest_framework.exceptions import PermissionDenied
from rest_framework.generics import ListAPIView
from rest_framework.permissions import IsAuthenticated
from apps.announcements.models import Announcement
from apps.courses.api.permissions import IsCourseOwner, IsTeacher
from apps.courses.models import Course, CourseStatus
from apps.enrollments.api.permissions import IsStudent
from apps.enrollments.models import Enrollment
from .serializers import AnnouncementSerializer, AnnouncementWriteSerializer
@extend_schema(tags=["announcements"])
class InstructorAnnouncementViewSet(viewsets.ModelViewSet):
"""Instructor CRUD over announcements on their own courses."""
permission_classes = [IsAuthenticated, IsTeacher, IsCourseOwner]
queryset = Announcement.objects.all().select_related("course", "posted_by")
filterset_fields = ["course"]
ordering = ["-created_at"]
def get_queryset(self):
return super().get_queryset().filter(course__instructor=self.request.user)
def get_serializer_class(self):
if self.action in {"create", "update", "partial_update"}:
return AnnouncementWriteSerializer
return AnnouncementSerializer
def perform_create(self, serializer):
course = serializer.validated_data["course"]
if course.instructor_id != self.request.user.id:
raise PermissionDenied("You don't own this course.")
announcement = serializer.save(posted_by=self.request.user)
# Record activity event for the instructor's home feed
from apps.enrollments.models import ActivityKind
from apps.enrollments.services.events import record_event
record_event(
course=course,
actor=self.request.user,
kind=ActivityKind.ANNOUNCEMENT_POSTED.value,
payload={
"announcement_id": announcement.pk,
"preview": (announcement.body or "")[:120],
},
)
class MyCourseAnnouncementsView(ListAPIView):
"""Student-facing list: announcements for a specific course the student is enrolled in."""
permission_classes = [IsAuthenticated, IsStudent]
serializer_class = AnnouncementSerializer
pagination_class = None
@extend_schema(
tags=["announcements"],
summary="My course announcements",
description="Lists all announcements posted by the instructor on a course the student is enrolled in.",
responses={
200: AnnouncementSerializer(many=True),
403: OpenApiResponse(description="Not enrolled."),
404: OpenApiResponse(description="Course not found or not published."),
},
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
def get_queryset(self):
slug = self.kwargs["slug"]
course = get_object_or_404(Course, slug=slug, status=CourseStatus.PUBLISHED)
if not Enrollment.objects.filter(student=self.request.user, course=course).exists():
raise PermissionDenied("You are not enrolled in this course.")
return (
Announcement.objects
.filter(course=course)
.select_related("posted_by")
.order_by("-created_at")
)