- Post 모델 개선 (author_id, updated_at, view_count 등) - Tag 모델 및 태그 기능 추가 - 댓글 기능 추가 - API 확장 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -1,10 +1,110 @@
|
||||
# blog/serializers.py
|
||||
|
||||
from rest_framework import serializers
|
||||
from .models import Post
|
||||
from .models import Post, Comment, Tag
|
||||
|
||||
|
||||
class TagSerializer(serializers.ModelSerializer):
|
||||
"""태그 시리얼라이저"""
|
||||
post_count = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Tag
|
||||
fields = ['id', 'name', 'post_count']
|
||||
read_only_fields = ['id']
|
||||
|
||||
def get_post_count(self, obj):
|
||||
return obj.posts.count()
|
||||
|
||||
|
||||
class CommentSerializer(serializers.ModelSerializer):
|
||||
"""댓글/대댓글 시리얼라이저"""
|
||||
replies = serializers.SerializerMethodField()
|
||||
reply_count = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = [
|
||||
'id', 'post', 'parent', 'content',
|
||||
'author_id', 'author_name',
|
||||
'created_at', 'updated_at',
|
||||
'reply_count', 'replies'
|
||||
]
|
||||
read_only_fields = ['author_id', 'author_name', 'post', 'created_at', 'updated_at']
|
||||
|
||||
def get_replies(self, obj):
|
||||
# 최상위 댓글의 대댓글만 반환
|
||||
if obj.parent is None:
|
||||
replies = obj.replies.all()
|
||||
return CommentSerializer(replies, many=True, context=self.context).data
|
||||
return []
|
||||
|
||||
def get_reply_count(self, obj):
|
||||
if obj.parent is None:
|
||||
return obj.replies.count()
|
||||
return 0
|
||||
|
||||
|
||||
class PostSerializer(serializers.ModelSerializer):
|
||||
comment_count = serializers.SerializerMethodField()
|
||||
tags = TagSerializer(many=True, read_only=True)
|
||||
tag_names = serializers.ListField(
|
||||
child=serializers.CharField(max_length=50),
|
||||
write_only=True,
|
||||
required=False
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = Post
|
||||
fields = ['id', 'title', 'content', 'author_name', 'created_at']
|
||||
read_only_fields = ['author_name', 'created_at']
|
||||
fields = [
|
||||
'id', 'title', 'content',
|
||||
'author_id', 'author_name',
|
||||
'created_at', 'updated_at',
|
||||
'comment_count', 'tags', 'tag_names'
|
||||
]
|
||||
read_only_fields = ['author_id', 'author_name', 'created_at', 'updated_at']
|
||||
|
||||
def get_comment_count(self, obj):
|
||||
return obj.comments.count()
|
||||
|
||||
def create(self, validated_data):
|
||||
tag_names = validated_data.pop('tag_names', [])
|
||||
post = Post.objects.create(**validated_data)
|
||||
self._set_tags(post, tag_names)
|
||||
return post
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
tag_names = validated_data.pop('tag_names', None)
|
||||
for attr, value in validated_data.items():
|
||||
setattr(instance, attr, value)
|
||||
instance.save()
|
||||
if tag_names is not None:
|
||||
self._set_tags(instance, tag_names)
|
||||
return instance
|
||||
|
||||
def _set_tags(self, post, tag_names):
|
||||
"""태그 설정 (없으면 생성)"""
|
||||
tags = []
|
||||
for name in tag_names:
|
||||
name = name.strip().lower()
|
||||
if name:
|
||||
tag, _ = Tag.objects.get_or_create(name=name)
|
||||
tags.append(tag)
|
||||
post.tags.set(tags)
|
||||
|
||||
|
||||
class PostListSerializer(serializers.ModelSerializer):
|
||||
"""목록 조회용 간소화된 시리얼라이저"""
|
||||
comment_count = serializers.SerializerMethodField()
|
||||
tags = TagSerializer(many=True, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Post
|
||||
fields = [
|
||||
'id', 'title',
|
||||
'author_name', 'created_at', 'updated_at',
|
||||
'comment_count', 'tags'
|
||||
]
|
||||
|
||||
def get_comment_count(self, obj):
|
||||
return obj.comments.count()
|
||||
|
||||
Reference in New Issue
Block a user