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.
230 lines
8.7 KiB
230 lines
8.7 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", "created_at", "updated_at"]
|
|
read_only_fields = ["id", "created_at", "updated_at"]
|
|
|
|
|
|
class AdminAuthorSerializer(serializers.ModelSerializer):
|
|
thumbnail = AbsoluteImageField(required=False, allow_null=True)
|
|
image = AbsoluteImageField(required=False, allow_null=True)
|
|
books_count = serializers.SerializerMethodField()
|
|
remove_thumbnail = serializers.BooleanField(write_only=True, required=False, default=False)
|
|
remove_image = serializers.BooleanField(write_only=True, required=False, default=False)
|
|
|
|
class Meta:
|
|
model = Author
|
|
fields = [
|
|
"id", "full_name", "slug", "thumbnail", "image", "birth_date", "death_date",
|
|
"date_of_birth", "date_of_death", "researcher_editor", "publisher",
|
|
"publication_place", "edition_statement", "year", "number_of_volumes",
|
|
"notes", "online_source", "tag", "books_count", "created_at", "updated_at",
|
|
"remove_thumbnail", "remove_image"
|
|
]
|
|
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)
|
|
validated_data.pop("remove_image", False)
|
|
return super().create(validated_data)
|
|
|
|
def update(self, instance, validated_data):
|
|
remove_thumbnail = validated_data.pop("remove_thumbnail", False)
|
|
remove_image = validated_data.pop("remove_image", False)
|
|
if remove_thumbnail and instance.thumbnail:
|
|
instance.thumbnail.delete(save=False)
|
|
instance.thumbnail = None
|
|
if remove_image and instance.image:
|
|
instance.image.delete(save=False)
|
|
instance.image = 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
|
|
)
|
|
|
|
bookmark_count = serializers.SerializerMethodField()
|
|
|
|
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",
|
|
"bookmark_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", "bookmark_count", "created_at", "updated_at"]
|
|
|
|
def get_bookmark_count(self, obj):
|
|
from apps.bookmark.models.bookmark import Bookmark
|
|
return Bookmark.objects.filter(service=Bookmark.ServiceChoices.LIBRARY, content_id=obj.id, status=True).count()
|
|
|
|
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
|