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.
263 lines
8.0 KiB
263 lines
8.0 KiB
from django.contrib.auth import get_user_model
|
|
from rest_framework import serializers
|
|
from drf_spectacular.utils import extend_schema_field
|
|
|
|
from apps.cms.models.post import (
|
|
PostCategory,
|
|
PostTag,
|
|
Post,
|
|
PostComment,
|
|
PostLike,
|
|
MediaAsset,
|
|
)
|
|
from apps.profiles.models.institution import Institution
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class PostCategorySerializer(serializers.ModelSerializer):
|
|
posts_count = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = PostCategory
|
|
fields = [
|
|
'id',
|
|
'name',
|
|
'slug',
|
|
'language',
|
|
'description',
|
|
'created_at',
|
|
'posts_count',
|
|
]
|
|
read_only_fields = ['id', 'slug', 'created_at', 'posts_count']
|
|
|
|
@extend_schema_field(serializers.IntegerField)
|
|
def get_posts_count(self, obj) -> int:
|
|
return obj.posts.filter(status=Post.Status.PUBLISHED).count()
|
|
|
|
|
|
class PostTagSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = PostTag
|
|
fields = ['id', 'name', 'slug']
|
|
read_only_fields = ['id', 'slug']
|
|
|
|
|
|
class PostAuthorMiniSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = User
|
|
fields = ['id', 'email', 'fullname', 'avatar']
|
|
read_only_fields = fields
|
|
|
|
|
|
class PostInstitutionMiniSerializer(serializers.ModelSerializer):
|
|
type_display = serializers.CharField(source='get_type_display', read_only=True)
|
|
|
|
class Meta:
|
|
model = Institution
|
|
fields = ['id', 'name', 'slug', 'type', 'type_display', 'avatar', 'city', 'country']
|
|
read_only_fields = fields
|
|
|
|
|
|
class PostCommentSerializer(serializers.ModelSerializer):
|
|
user = PostAuthorMiniSerializer(read_only=True)
|
|
status_display = serializers.CharField(source='get_status_display', read_only=True)
|
|
|
|
class Meta:
|
|
model = PostComment
|
|
fields = [
|
|
'id',
|
|
'post',
|
|
'user',
|
|
'author_name',
|
|
'author_email',
|
|
'content',
|
|
'status',
|
|
'status_display',
|
|
'created_at',
|
|
]
|
|
read_only_fields = ['id', 'post', 'user', 'status', 'status_display', 'created_at']
|
|
|
|
|
|
class PostCommentCreateSerializer(serializers.Serializer):
|
|
content = serializers.CharField(required=True)
|
|
author_name = serializers.CharField(required=False, allow_blank=True, max_length=255)
|
|
author_email = serializers.EmailField(required=False, allow_blank=True)
|
|
|
|
|
|
class PostListSerializer(serializers.ModelSerializer):
|
|
post_type_display = serializers.CharField(source='get_post_type_display', read_only=True)
|
|
category_name = serializers.CharField(source='category.name', read_only=True, allow_null=True)
|
|
author = PostAuthorMiniSerializer(read_only=True)
|
|
institution = PostInstitutionMiniSerializer(read_only=True)
|
|
comments_count = serializers.SerializerMethodField()
|
|
is_liked = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Post
|
|
fields = [
|
|
'id',
|
|
'title',
|
|
'slug',
|
|
'post_type',
|
|
'post_type_display',
|
|
'category',
|
|
'category_name',
|
|
'language',
|
|
'status',
|
|
'author',
|
|
'institution',
|
|
'author_role_label',
|
|
'author_custom_avatar',
|
|
'featured_image',
|
|
'excerpt',
|
|
'tags',
|
|
'reading_time_minutes',
|
|
'views_count',
|
|
'likes_count',
|
|
'comments_count',
|
|
'is_featured',
|
|
'publish_date',
|
|
'is_liked',
|
|
'created_at',
|
|
]
|
|
read_only_fields = fields
|
|
|
|
@extend_schema_field(serializers.IntegerField)
|
|
def get_comments_count(self, obj) -> int:
|
|
return obj.comments.filter(status=PostComment.Status.APPROVED).count()
|
|
|
|
@extend_schema_field(serializers.BooleanField)
|
|
def get_is_liked(self, obj) -> bool:
|
|
request = self.context.get('request')
|
|
if not request or not request.user.is_authenticated:
|
|
return False
|
|
return obj.is_liked_by(request.user)
|
|
|
|
|
|
class PostDetailSerializer(serializers.ModelSerializer):
|
|
post_type_display = serializers.CharField(source='get_post_type_display', read_only=True)
|
|
category = PostCategorySerializer(read_only=True)
|
|
author = PostAuthorMiniSerializer(read_only=True)
|
|
institution = PostInstitutionMiniSerializer(read_only=True)
|
|
comments = serializers.SerializerMethodField()
|
|
comments_count = serializers.SerializerMethodField()
|
|
is_liked = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Post
|
|
fields = [
|
|
'id',
|
|
'title',
|
|
'slug',
|
|
'post_type',
|
|
'post_type_display',
|
|
'category',
|
|
'language',
|
|
'status',
|
|
'author',
|
|
'institution',
|
|
'author_role_label',
|
|
'author_custom_avatar',
|
|
'featured_image',
|
|
'excerpt',
|
|
'content',
|
|
'tags',
|
|
'reading_time_minutes',
|
|
'views_count',
|
|
'likes_count',
|
|
'comments_count',
|
|
'is_featured',
|
|
'publish_date',
|
|
'is_liked',
|
|
'comments',
|
|
'created_at',
|
|
'updated_at',
|
|
]
|
|
read_only_fields = [
|
|
'id',
|
|
'slug',
|
|
'reading_time_minutes',
|
|
'views_count',
|
|
'likes_count',
|
|
'comments_count',
|
|
'is_liked',
|
|
'comments',
|
|
'created_at',
|
|
'updated_at',
|
|
]
|
|
|
|
@extend_schema_field(PostCommentSerializer(many=True))
|
|
def get_comments(self, obj):
|
|
approved_comments = obj.comments.filter(status=PostComment.Status.APPROVED).order_by('-created_at')
|
|
return PostCommentSerializer(approved_comments, many=True).data
|
|
|
|
@extend_schema_field(serializers.IntegerField)
|
|
def get_comments_count(self, obj) -> int:
|
|
return obj.comments.filter(status=PostComment.Status.APPROVED).count()
|
|
|
|
@extend_schema_field(serializers.BooleanField)
|
|
def get_is_liked(self, obj) -> bool:
|
|
request = self.context.get('request')
|
|
if not request or not request.user.is_authenticated:
|
|
return False
|
|
return obj.is_liked_by(request.user)
|
|
|
|
|
|
class PostCreateUpdateSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Post
|
|
fields = [
|
|
'title',
|
|
'post_type',
|
|
'category',
|
|
'language',
|
|
'status',
|
|
'institution',
|
|
'author_role_label',
|
|
'author_custom_avatar',
|
|
'featured_image',
|
|
'excerpt',
|
|
'content',
|
|
'tags',
|
|
'is_featured',
|
|
'publish_date',
|
|
]
|
|
|
|
def create(self, validated_data):
|
|
request = self.context.get('request')
|
|
if request and request.user.is_authenticated:
|
|
validated_data['author'] = request.user
|
|
return super().create(validated_data)
|
|
|
|
|
|
class PostLikeResponseSerializer(serializers.Serializer):
|
|
is_liked = serializers.BooleanField()
|
|
likes_count = serializers.IntegerField()
|
|
message = serializers.CharField()
|
|
|
|
|
|
class MediaAssetSerializer(serializers.ModelSerializer):
|
|
media_type_display = serializers.CharField(source='get_media_type_display', read_only=True)
|
|
uploaded_by_email = serializers.EmailField(source='uploaded_by.email', read_only=True, allow_null=True)
|
|
|
|
class Meta:
|
|
model = MediaAsset
|
|
fields = [
|
|
'id',
|
|
'file',
|
|
'title',
|
|
'media_type',
|
|
'media_type_display',
|
|
'file_size',
|
|
'dimensions',
|
|
'uploaded_by_email',
|
|
'created_at',
|
|
]
|
|
read_only_fields = ['id', 'media_type_display', 'file_size', 'uploaded_by_email', 'created_at']
|
|
|
|
def create(self, validated_data):
|
|
request = self.context.get('request')
|
|
if request and request.user.is_authenticated:
|
|
validated_data['uploaded_by'] = request.user
|
|
return super().create(validated_data)
|