3 changed files with 172 additions and 2 deletions
@ -0,0 +1,119 @@ |
|||
from rest_framework import serializers |
|||
|
|||
from .models import Video |
|||
|
|||
|
|||
class AbsoluteImageField(serializers.ImageField): |
|||
def to_representation(self, value): |
|||
if not value: |
|||
return None |
|||
request = self.context.get("request") |
|||
url = value.url if hasattr(value, "url") else str(value) |
|||
if request: |
|||
return request.build_absolute_uri(url) |
|||
return url |
|||
|
|||
|
|||
class AbsoluteFileField(serializers.FileField): |
|||
def to_representation(self, value): |
|||
if not value: |
|||
return None |
|||
request = self.context.get("request") |
|||
url = value.url if hasattr(value, "url") else str(value) |
|||
if request: |
|||
return request.build_absolute_uri(url) |
|||
return url |
|||
|
|||
|
|||
class AdminVideoListSerializer(serializers.ModelSerializer): |
|||
thumbnail = AbsoluteImageField(required=False, allow_null=True) |
|||
video_file = AbsoluteFileField(required=False, allow_null=True) |
|||
|
|||
class Meta: |
|||
model = Video |
|||
fields = [ |
|||
"id", |
|||
"title", |
|||
"slug", |
|||
"thumbnail", |
|||
"description", |
|||
"video_type", |
|||
"video_file", |
|||
"video_url", |
|||
"video_time", |
|||
"status", |
|||
"view_count", |
|||
"created_at", |
|||
"updated_at", |
|||
] |
|||
read_only_fields = ["id", "view_count", "created_at", "updated_at"] |
|||
|
|||
|
|||
class AdminVideoDetailSerializer(serializers.ModelSerializer): |
|||
thumbnail = AbsoluteImageField(required=False, allow_null=True) |
|||
video_file = AbsoluteFileField(required=False, allow_null=True) |
|||
remove_thumbnail = serializers.BooleanField(write_only=True, required=False, default=False) |
|||
remove_video_file = serializers.BooleanField(write_only=True, required=False, default=False) |
|||
|
|||
class Meta: |
|||
model = Video |
|||
fields = [ |
|||
"id", |
|||
"title", |
|||
"slug", |
|||
"thumbnail", |
|||
"description", |
|||
"video_type", |
|||
"video_file", |
|||
"video_url", |
|||
"video_time", |
|||
"status", |
|||
"view_count", |
|||
"created_at", |
|||
"updated_at", |
|||
"remove_thumbnail", |
|||
"remove_video_file", |
|||
] |
|||
read_only_fields = ["id", "view_count", "created_at", "updated_at"] |
|||
|
|||
def validate(self, attrs): |
|||
video_type = attrs.get("video_type", getattr(self.instance, "video_type", None)) |
|||
video_url = attrs.get("video_url", getattr(self.instance, "video_url", None)) |
|||
video_file = attrs.get("video_file", getattr(self.instance, "video_file", None)) |
|||
remove_video_file = attrs.get("remove_video_file", False) |
|||
|
|||
if video_type == Video.VedioTypeChoices.YOUTUBE_LINK and not video_url: |
|||
raise serializers.ValidationError({ |
|||
"video_url": "This field is required when video type is link.", |
|||
}) |
|||
|
|||
if video_type == Video.VedioTypeChoices.VIDEO_FILE and not video_file and not getattr(self.instance, "video_file", None): |
|||
raise serializers.ValidationError({ |
|||
"video_file": "This field is required when video type is file.", |
|||
}) |
|||
|
|||
if video_type == Video.VedioTypeChoices.VIDEO_FILE and remove_video_file and "video_file" not in attrs: |
|||
raise serializers.ValidationError({ |
|||
"video_file": "Please upload a new file before removing the current one.", |
|||
}) |
|||
|
|||
return attrs |
|||
|
|||
def create(self, validated_data): |
|||
validated_data.pop("remove_thumbnail", False) |
|||
validated_data.pop("remove_video_file", False) |
|||
return super().create(validated_data) |
|||
|
|||
def update(self, instance, validated_data): |
|||
remove_thumbnail = validated_data.pop("remove_thumbnail", False) |
|||
remove_video_file = validated_data.pop("remove_video_file", False) |
|||
|
|||
if remove_thumbnail and instance.thumbnail: |
|||
instance.thumbnail.delete(save=False) |
|||
instance.thumbnail = None |
|||
|
|||
if remove_video_file and instance.video_file: |
|||
instance.video_file.delete(save=False) |
|||
instance.video_file = None |
|||
|
|||
return super().update(instance, validated_data) |
|||
@ -0,0 +1,45 @@ |
|||
from django.db.models import Q |
|||
from rest_framework.authentication import TokenAuthentication |
|||
from rest_framework.parsers import FormParser, JSONParser, MultiPartParser |
|||
from rest_framework.permissions import IsAuthenticated |
|||
from rest_framework.viewsets import ModelViewSet |
|||
|
|||
from apps.account.permissions import IsSuperAdmin |
|||
from utils.pagination import StandardResultsSetPagination |
|||
|
|||
from .models import Video |
|||
from .serializers_admin import AdminVideoDetailSerializer, AdminVideoListSerializer |
|||
|
|||
|
|||
class AdminVideoViewSet(ModelViewSet): |
|||
permission_classes = [IsAuthenticated, IsSuperAdmin] |
|||
authentication_classes = [TokenAuthentication] |
|||
pagination_class = StandardResultsSetPagination |
|||
parser_classes = (MultiPartParser, FormParser, JSONParser) |
|||
|
|||
def get_serializer_class(self): |
|||
if self.action == "list": |
|||
return AdminVideoListSerializer |
|||
return AdminVideoDetailSerializer |
|||
|
|||
def get_queryset(self): |
|||
queryset = Video.objects.all() |
|||
|
|||
search_query = self.request.query_params.get("search") |
|||
if search_query: |
|||
queryset = queryset.filter( |
|||
Q(title__icontains=search_query) |
|||
| Q(slug__icontains=search_query) |
|||
| Q(description__icontains=search_query) |
|||
| Q(video_url__icontains=search_query) |
|||
) |
|||
|
|||
status_filter = self.request.query_params.get("status") |
|||
if status_filter in {"true", "false"}: |
|||
queryset = queryset.filter(status=status_filter == "true") |
|||
|
|||
video_type = self.request.query_params.get("video_type") |
|||
if video_type and video_type != "all": |
|||
queryset = queryset.filter(video_type=video_type) |
|||
|
|||
return queryset.order_by("-created_at") |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue