Browse Source

library views and serializers for admin panel added

master
Mohsen Taba 1 month ago
parent
commit
3b50aa2b1b
  1. 8
      apps/library/serializers.py
  2. 152
      apps/library/serializers_admin.py
  3. 12
      apps/library/urls.py
  4. 80
      apps/library/views_admin.py

8
apps/library/serializers.py

@ -46,13 +46,19 @@ class PinnedBookCollectionSerializer(serializers.ModelSerializer):
model = BookCollection model = BookCollection
fields = ('id', 'title', 'summary', 'covers') fields = ('id', 'title', 'summary', 'covers')
from dj_language.models import Language
class BookSerializer(serializers.ModelSerializer): class BookSerializer(serializers.ModelSerializer):
thumbnail = serializers.SerializerMethodField() thumbnail = serializers.SerializerMethodField()
bookmark = serializers.SerializerMethodField() bookmark = serializers.SerializerMethodField()
user_rate = serializers.SerializerMethodField() user_rate = serializers.SerializerMethodField()
average_rate = serializers.SerializerMethodField() average_rate = serializers.SerializerMethodField()
share_link = serializers.CharField(read_only=True) share_link = serializers.CharField(read_only=True)
language = serializers.SlugRelatedField(
slug_field='code',
queryset=Language.objects.all(),
allow_null=True,
required=False
)
def get_thumbnail(self, obj): def get_thumbnail(self, obj):
if obj.thumbnail: if obj.thumbnail:

152
apps/library/serializers_admin.py

@ -0,0 +1,152 @@
from rest_framework import serializers
from .models import Book, BookCollection, Category
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 AdminLibraryCategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ["id", "title", "slug", "status", "created_at", "updated_at"]
class AdminLibraryCollectionSerializer(serializers.ModelSerializer):
class Meta:
model = BookCollection
fields = ["id", "title", "slug", "summary", "display_position", "status", "order", "pin_top"]
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)
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",
"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)
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",
"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

12
apps/library/urls.py

@ -1,4 +1,5 @@
from django.urls import path
from django.urls import include, path
from rest_framework.routers import SimpleRouter
from apps.library.views import ( from apps.library.views import (
CategoryListView, CategoryListView,
@ -9,8 +10,15 @@ from apps.library.views import (
DownloadedBooksListView, DownloadedBooksListView,
BookDownloadCreateAPIView, BookDownloadCreateAPIView,
) )
from apps.library.views_admin import AdminBookViewSet, AdminLibraryCategoryViewSet, AdminLibraryCollectionViewSet
admin_router = SimpleRouter()
admin_router.register(r'books', AdminBookViewSet, basename='admin-library-books')
admin_router.register(r'categories', AdminLibraryCategoryViewSet, basename='admin-library-categories')
admin_router.register(r'collections', AdminLibraryCollectionViewSet, basename='admin-library-collections')
urlpatterns = [ urlpatterns = [
path('admin/', include(admin_router.urls)),
path('categories/', CategoryListView.as_view(), name='category-list'), path('categories/', CategoryListView.as_view(), name='category-list'),
path('pinned-collections/', PinnedBookCollectionListView.as_view(), name='pinned-collection-list'), path('pinned-collections/', PinnedBookCollectionListView.as_view(), name='pinned-collection-list'),
path('collections/', MiddleBookCollectionListView.as_view(), name='collection-list'), path('collections/', MiddleBookCollectionListView.as_view(), name='collection-list'),
@ -18,4 +26,4 @@ urlpatterns = [
path('books/<str:slug>/', BookDetailView.as_view(), name='book-detail'), path('books/<str:slug>/', BookDetailView.as_view(), name='book-detail'),
path('books/downloaded/', DownloadedBooksListView.as_view(), name='downloaded-books-list'), path('books/downloaded/', DownloadedBooksListView.as_view(), name='downloaded-books-list'),
path('books/download/', BookDownloadCreateAPIView.as_view(), name='book-download'), path('books/download/', BookDownloadCreateAPIView.as_view(), name='book-download'),
]
]

80
apps/library/views_admin.py

@ -0,0 +1,80 @@
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, ReadOnlyModelViewSet
from apps.account.permissions import IsSuperAdmin
from utils.pagination import StandardResultsSetPagination
from .models import Book, BookCollection, Category
from .serializers_admin import (
AdminBookDetailSerializer,
AdminBookListSerializer,
AdminLibraryCategorySerializer,
AdminLibraryCollectionSerializer,
)
class AdminLibraryCategoryViewSet(ReadOnlyModelViewSet):
serializer_class = AdminLibraryCategorySerializer
permission_classes = [IsAuthenticated, IsSuperAdmin]
authentication_classes = [TokenAuthentication]
pagination_class = None
def get_queryset(self):
return Category.objects.all().order_by("title")
class AdminLibraryCollectionViewSet(ReadOnlyModelViewSet):
serializer_class = AdminLibraryCollectionSerializer
permission_classes = [IsAuthenticated, IsSuperAdmin]
authentication_classes = [TokenAuthentication]
pagination_class = None
def get_queryset(self):
return BookCollection.objects.all().order_by("display_position", "order", "title")
class AdminBookViewSet(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 AdminBookListSerializer
return AdminBookDetailSerializer
def get_queryset(self):
queryset = Book.objects.all().prefetch_related("categories", "collections")
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(author__icontains=search_query)
| Q(publisher__icontains=search_query)
| Q(isbn__icontains=search_query)
| Q(summary__icontains=search_query)
)
status_filter = self.request.query_params.get("status")
if status_filter in {"true", "false"}:
queryset = queryset.filter(status=status_filter == "true")
file_type = self.request.query_params.get("file_type")
if file_type and file_type != "all":
queryset = queryset.filter(file_type=file_type)
category_id = self.request.query_params.get("category")
if category_id and category_id != "all":
queryset = queryset.filter(categories__id=category_id)
collection_id = self.request.query_params.get("collection")
if collection_id and collection_id != "all":
queryset = queryset.filter(collections__id=collection_id)
return queryset.distinct().order_by("-created_at")
Loading…
Cancel
Save