gallery-backend/publications/serializers.py
2026-01-07 20:09:26 +01:00

71 lines
2.4 KiB
Python

from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from drf_spectacular.utils import extend_schema_field
from users.serializers import PublicUserSerializer
from .models import Publication, Rating, Category
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ('pk', 'name')
class PublicationSerializer(serializers.ModelSerializer):
category_detail = CategorySerializer(source="category", read_only=True)
user_detail = PublicUserSerializer(source="user", read_only=True)
average_score = serializers.SerializerMethodField(read_only=True)
@extend_schema_field(serializers.FloatField())
def get_average_score(self, obj):
return getattr(obj, 'average_score', 0)
def validate(self, attrs):
content_type = attrs.get(
'content_type',
getattr(self.instance, 'content_type', None)
)
image = attrs.get(
'image',
getattr(self.instance, 'image', None)
)
video = attrs.get(
'video',
getattr(self.instance, 'video', None)
)
errors = {}
if content_type == 'image' and not image:
errors['image'] = 'Required image file'
if content_type == 'video' and not video:
errors['video'] = 'Required video file'
if image and video:
errors['non_field_errors'] = 'You must upload either a video or an image, not both'
if errors:
raise serializers.ValidationError(errors)
return attrs
class Meta:
model = Publication
fields = ('pk', 'image', 'video', 'content_type', 'status', 'average_score', 'description', 'is_pinned', 'user', 'user_detail', 'category', 'category_detail','time_created', 'time_updated')
read_only_fields = ('time_created', 'time_updated', 'is_pinned', 'user', 'status')
class AdminPublicationSerializer(PublicationSerializer):
class Meta(PublicationSerializer.Meta):
read_only_fields = ('time_created', 'time_updated', 'user')
class RatePublicationSerializer(serializers.Serializer):
score = serializers.IntegerField()
publication = serializers.PrimaryKeyRelatedField(queryset=Publication.objects.only_publish())
def validate_score(self, value):
if value > 5 or value < 1:
raise ValidationError('Score must be between 1 and 5')
return value