Jakub Kaniecki 12c76e3e5a init
2025-05-18 16:23:03 +02:00

202 lines
7.3 KiB
Python

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']