You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

209 lines
7.6 KiB

from rest_framework import serializers
from django.core.files.uploadedfile import SimpleUploadedFile
from utils.image_compression import maybe_compress_uploaded_file
from .models import Author, Book, BookCollection, Category
class AbsoluteImageField(serializers.ImageField):
def to_internal_value(self, data):
uploaded = super().to_internal_value(data)
compressed_bytes = maybe_compress_uploaded_file(uploaded)
if compressed_bytes is None:
return uploaded
return SimpleUploadedFile(
name=getattr(uploaded, "name", "image"),
content=compressed_bytes,
content_type=getattr(uploaded, "content_type", None),
)
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 AdminLibraryCategorySerializer(serializers.ModelSerializer):
books_count = serializers.SerializerMethodField()
class Meta:
model = Category
fields = ["id", "title", "slug", "status", "books_count", "created_at", "updated_at"]
read_only_fields = ["id", "books_count", "created_at", "updated_at"]
def get_books_count(self, obj):
if hasattr(obj, "books_count_annotation"):
return obj.books_count_annotation
return obj.books_count
class AdminLibraryCollectionSerializer(serializers.ModelSerializer):
slug = serializers.CharField(required=False, allow_blank=True)
class Meta:
model = BookCollection
fields = ["id", "title", "slug", "summary", "display_position", "status", "order", "pin_top"]
class AdminAuthorSerializer(serializers.ModelSerializer):
thumbnail = AbsoluteImageField(required=False, allow_null=True)
books_count = serializers.SerializerMethodField()
remove_thumbnail = serializers.BooleanField(write_only=True, required=False, default=False)
class Meta:
model = Author
fields = ["id", "full_name", "slug", "thumbnail", "birth_date", "death_date", "books_count", "created_at", "updated_at", "remove_thumbnail"]
read_only_fields = ["id", "created_at", "updated_at", "books_count"]
def get_books_count(self, obj):
if hasattr(obj, 'books_count_annotation'):
return obj.books_count_annotation
return obj.books_count
def create(self, validated_data):
validated_data.pop("remove_thumbnail", False)
return super().create(validated_data)
def update(self, instance, validated_data):
remove_thumbnail = validated_data.pop("remove_thumbnail", False)
if remove_thumbnail and instance.thumbnail:
instance.thumbnail.delete(save=False)
instance.thumbnail = None
return super().update(instance, validated_data)
class AdminBookListSerializer(serializers.ModelSerializer):
thumbnail = AbsoluteImageField(required=False, allow_null=True)
book_file = AbsoluteFileField(required=False, allow_null=True)
categories_detail = AdminLibraryCategorySerializer(source="categories", many=True, read_only=True)
author = serializers.CharField(source='author.full_name', read_only=True)
author_id = serializers.IntegerField(read_only=True)
class Meta:
model = Book
fields = [
"id",
"title",
"slug",
"slogan",
"thumbnail",
"author",
"publisher",
"file_type",
"status",
"pin",
"view_count",
"download_count",
"created_at",
"updated_at",
"categories_detail",
"author_id",
"book_file",
]
read_only_fields = ["id", "view_count", "download_count", "created_at", "updated_at"]
from dj_language.models import Language
class AdminBookDetailSerializer(serializers.ModelSerializer):
thumbnail = AbsoluteImageField(required=False, allow_null=True)
book_file = AbsoluteFileField(required=False, allow_null=True)
author = serializers.PrimaryKeyRelatedField(queryset=Author.objects.all(), required=False, allow_null=True)
author_detail = AdminAuthorSerializer(source='author', read_only=True)
categories = serializers.PrimaryKeyRelatedField(queryset=Category.objects.all(), many=True, required=False)
collections = serializers.PrimaryKeyRelatedField(queryset=BookCollection.objects.all(), many=True, required=False)
categories_detail = AdminLibraryCategorySerializer(source="categories", many=True, read_only=True)
collections_detail = AdminLibraryCollectionSerializer(source="collections", many=True, read_only=True)
remove_thumbnail = serializers.BooleanField(write_only=True, required=False, default=False)
remove_book_file = serializers.BooleanField(write_only=True, required=False, default=False)
language = serializers.SlugRelatedField(
slug_field='code',
queryset=Language.objects.all(),
allow_null=True,
required=False
)
class Meta:
model = Book
fields = [
"id",
"title",
"slug",
"slogan",
"summary_title",
"summary",
"description",
"thumbnail",
"publisher",
"year_of_publication",
"author",
"author_detail",
"isbn",
"numnber_of_volume",
"language",
"main_themes",
"notable_works",
"pages_count",
"status",
"pin",
"view_count",
"download_count",
"file_type",
"book_file",
"created_at",
"updated_at",
"categories",
"collections",
"categories_detail",
"collections_detail",
"remove_thumbnail",
"remove_book_file",
]
read_only_fields = ["id", "view_count", "download_count", "created_at", "updated_at"]
def create(self, validated_data):
validated_data.pop("remove_thumbnail", False)
validated_data.pop("remove_book_file", False)
categories = validated_data.pop("categories", [])
collections = validated_data.pop("collections", [])
book = super().create(validated_data)
if categories:
book.categories.set(categories)
if collections:
book.collections.set(collections)
return book
def update(self, instance, validated_data):
remove_thumbnail = validated_data.pop("remove_thumbnail", False)
remove_book_file = validated_data.pop("remove_book_file", False)
categories = validated_data.pop("categories", None)
collections = validated_data.pop("collections", None)
if remove_thumbnail and instance.thumbnail:
instance.thumbnail.delete(save=False)
instance.thumbnail = None
if remove_book_file and instance.book_file:
instance.book_file.delete(save=False)
instance.book_file = None
book = super().update(instance, validated_data)
if categories is not None:
book.categories.set(categories)
if collections is not None:
book.collections.set(collections)
return book