from rest_framework import viewsets, status, filters from rest_framework.response import Response from rest_framework.decorators import action from django_filters.rest_framework import DjangoFilterBackend from .models import Post, Comment, Page, Category, UploadedImage, Tag from .serializers import PostSerializer, CommentSerializer, PageSerializer, CategorySerializer, UploadedImageSerializer, TagSerializer from users.permissions import IsAuthorOrReadOnly, IsEditorOrAdmin from rest_framework.permissions import IsAuthenticatedOrReadOnly from rest_framework.parsers import MultiPartParser, FormParser from django.conf import settings from rest_framework import serializers class PostViewSet(viewsets.ModelViewSet): """ API endpoint for managing blog posts. list: Return a list of all posts. Results can be filtered by: - status (draft/pending/published) - author - category - created_at (date range) create: Create a new post. Requires authentication and appropriate permissions. retrieve: Return the details of a specific post by ID. update: Update all fields of a specific post. Requires authentication and appropriate permissions. partial_update: Update one or more fields of a specific post. Requires authentication and appropriate permissions. destroy: Delete a specific post. Requires authentication and appropriate permissions. """ queryset = Post.objects.all() serializer_class = PostSerializer permission_classes = [IsAuthorOrReadOnly] filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter] filterset_fields = ['status', 'author', 'category'] search_fields = ['title', 'content'] ordering_fields = ['created_at', 'updated_at', 'title'] ordering = ['-created_at'] lookup_field = 'slug' def perform_create(self, serializer): serializer.save(author=self.request.user) def get_queryset(self): queryset = Post.objects.all() if not self.request.user.is_authenticated: queryset = queryset.filter(status='published') elif not self.request.user.role in ['admin', 'moderator']: queryset = queryset.filter( status='published' ) | Post.objects.filter( author=self.request.user ) return queryset def perform_update(self, serializer): print(serializer.validated_data) return super().perform_update(serializer) class CommentViewSet(viewsets.ModelViewSet): """ API endpoint for managing comments on posts and pages. list: Return a list of all comments. Results can be filtered by: - post_id - page_id - author - approved status create: Create a new comment. Requires authentication. retrieve: Return the details of a specific comment by ID. update: Update all fields of a specific comment. Requires authentication and appropriate permissions. partial_update: Update one or more fields of a specific comment. Requires authentication and appropriate permissions. destroy: Delete a specific comment. Requires authentication and appropriate permissions. """ queryset = Comment.objects.all() serializer_class = CommentSerializer permission_classes = [IsAuthorOrReadOnly] filter_backends = [DjangoFilterBackend, filters.OrderingFilter] filterset_fields = ['post', 'page', 'author', 'approved'] ordering_fields = ['created_at'] ordering = ['-created_at'] def perform_create(self, serializer): serializer.save(author=self.request.user) def get_queryset(self): queryset = Comment.objects.all() if not self.request.user.is_authenticated: queryset = queryset.filter(approved=True) elif not self.request.user.role in ['admin', 'moderator']: queryset = queryset.filter( approved=True ) | Comment.objects.filter( author=self.request.user ) return queryset class PageViewSet(viewsets.ModelViewSet): queryset = Page.objects.all() serializer_class = PageSerializer permission_classes = [IsEditorOrAdmin] filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter] filterset_fields = ['status', 'author', 'category'] search_fields = ['title', 'content'] ordering_fields = ['created_at', 'updated_at', 'title'] ordering = ['-created_at'] def perform_create(self, serializer): serializer.save(author=self.request.user) def get_queryset(self): queryset = Page.objects.all() if not self.request.user.is_authenticated: queryset = queryset.filter(status='published') elif not self.request.user.role in ['admin', 'moderator']: queryset = queryset.filter( status='published' ) | Page.objects.filter( author=self.request.user ) return queryset class CategoryViewSet(viewsets.ModelViewSet): queryset = Category.objects.all() serializer_class = CategorySerializer permission_classes = [IsAuthenticatedOrReadOnly] filter_backends = [filters.SearchFilter] search_fields = ['name', 'slug'] def get_queryset(self): return Category.objects.all() class UploadedImageViewSet(viewsets.ModelViewSet): serializer_class = UploadedImageSerializer parser_classes = (MultiPartParser, FormParser) def get_queryset(self): return UploadedImage.objects.filter(user=self.request.user) def get_serializer_context(self): context = super().get_serializer_context() context['request'] = self.request return context def perform_create(self, serializer): # Check daily upload quota (5MB = 5 * 1024 * 1024 bytes) DAILY_UPLOAD_LIMIT = 5 * 1024 * 1024 # 5MB in bytes # Get current daily upload size current_size = UploadedImage.get_user_daily_upload_size(self.request.user) file_size = self.request.FILES['image'].size # Check if upload would exceed daily limit if current_size + file_size > DAILY_UPLOAD_LIMIT: raise serializers.ValidationError({ 'image': 'Daily upload limit (5MB) exceeded. Please try again tomorrow.' }) try: instance = serializer.save(user=self.request.user, file_size=file_size) except Exception as e: raise @action(detail=False, methods=['get']) def quota(self, request): DAILY_UPLOAD_LIMIT = 5 * 1024 * 1024 # 5MB in bytes current_size = UploadedImage.get_user_daily_upload_size(request.user) remaining = max(0, DAILY_UPLOAD_LIMIT - current_size) return Response({ 'daily_limit': DAILY_UPLOAD_LIMIT, 'used': current_size, 'remaining': remaining, 'daily_limit_display': f"{DAILY_UPLOAD_LIMIT / (1024 * 1024):.1f}MB", 'used_display': f"{current_size / (1024 * 1024):.1f}MB", 'remaining_display': f"{remaining / (1024 * 1024):.1f}MB" }) class TagViewSet(viewsets.ModelViewSet): queryset = Tag.objects.all() serializer_class = TagSerializer permission_classes = [IsAuthenticatedOrReadOnly] filter_backends = [filters.SearchFilter] search_fields = ['name', 'slug']