202 lines
7.3 KiB
Python
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'] |