2026/02/25 ~ 2026/02/28 개인사정으로 인한 기록 불가
문제 해결
수정시에 태그가 수정이 안됨
- 수정시에 태그도 수정이 가능하도록 기능을 수정해야 함

<div class="row">
<div class="col-md-6 mb-4">
<label class="form-label fw-bold text-secondary">공개 설정</label>
<select class="form-select" id="visibility">
<option value="PUBLIC">전체 공개</option>
<option value="PRIVATE">비공개 (나만 보기)</option>
</select>
</div>
</div>
<div class="d-flex justify-content-end gap-2 mt-5 border-top pt-4">
——————————————————————————————————————[비교]—————————————————————————————————————————
<div class="row">
<div class="col-md-6 mb-4">
<label class="form-label fw-bold text-secondary">공개 설정</label>
<select class="form-select" id="visibility">
<option value="PUBLIC">전체 공개</option>
<option value="PRIVATE">비공개 (나만 보기)</option>
</select>
</div>
</div>
<div class="mb-4">
<label for="tags" class="form-label fw-bold text-secondary">태그</label>
<input type="text" class="form-control" id="tags" placeholder="예: Python, Django, 일상 (쉼표로 구분)">
</div>

좋아요 취소 오류
- 좋아요가 다시 눌림 다시 눌렀을 경우 삭제되지 않음

원인
- 사용자가 이 글에 좋아요를 눌렀는지 여부를 전달하지 않음
시리얼라이저 수정
class PostDetailSerializer(serializers.ModelSerializer):
author_nickname = serializers.CharField(source="user.nickname", read_only=True)
tags = serializers.SlugRelatedField(many=True, read_only=True, slug_field="name")
likes_count = serializers.IntegerField(read_only=True)
class Meta:
model = Post
fields = [
"id",
"title",
"content",
"thumbnail",
"author_nickname",
"created_at",
"visibility",
"tags",
"likes_count",
]
——————————————————————————————————————[비교]—————————————————————————————————————————
class PostDetailSerializer(serializers.ModelSerializer):
author_nickname = serializers.CharField(source="user.nickname", read_only=True)
tags = serializers.SlugRelatedField(many=True, read_only=True, slug_field="name")
likes_count = serializers.IntegerField(read_only=True)
is_liked = serializers.SerializerMethodField()
class Meta:
model = Post
fields = [
"id",
"title",
"content",
"thumbnail",
"author_nickname",
"created_at",
"visibility",
"tags",
"likes_count",
"is_liked",
]
def get_is_liked(self, obj) -> bool:
request = self.context.get('request')
if request and request.user.is_authenticated:
return obj.likes.filter(user=request.user).exists()
return False
class PostDetailAPIView(APIView):
permission_classes = [IsAuthenticatedOrReadOnly]
@extend_schema(tags=["포스트"], summary="게시글 상세 조회")
def get(self, request: Request, post_id: int):
post = get_post_detail(post_id)
if not post:
raise BaseCustomException(ErrorMessage.POST_NOT_FOUND)
return Response(PostDetailSerializer(post, context={'request': request}).data)
해결 완료

기능 개발

댓글 수정 api
view
class CommentManageAPIView(APIView):
"""게시글의 댓글 수정/삭제을 담당하는 View입니다."""
permission_classes = [IsAuthenticatedOrReadOnly]
@extend_schema(
tags=["댓글"],
summary="게시글 댓글 수정",
request=CommentCreateSerializer,
)
def put(self, request: Request, comment_id: int):
serializer = CommentCreateSerializer(data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
user = cast(User, request.user)
comment = update_comment(
comment_id=comment_id, user=user, validated_data=serializer.validated_data
)
return Response(
CommentCreateSerializer(comment).data,
status=status.HTTP_200_OK,
)
service
@transaction.atomic
def update_comment(
*, comment_id: int, user: User, validated_data: dict[str, Any]
) -> Comment:
comment = Comment.objects.filter(id=comment_id).first()
if not comment:
raise BaseCustomException(ErrorMessage.COMMENT_NOT_FOUND)
if comment.user != user:
raise BaseCustomException(ErrorMessage.NOT_COMMENT_AUTHOR)
if "content" in validated_data:
comment.content = validated_data["content"]
comment.save(update_fields=["content"])
return comment
댓글 삭제api
view
def delete(self, request: Request, comment_id: int):
user = cast(User, request.user)
delete_comment(comment_id=comment_id, user=user)
return Response(status=status.HTTP_204_NO_CONTENT)
service
@transaction.atomic
def delete_comment(*, comment_id: int, user: User) -> None:
"""댓글을 삭제하는 서비스 로직입니다."""
comment = Comment.objects.filter(id=comment_id).first()
if not comment:
raise BaseCustomException(ErrorMessage.COMMENT_NOT_FOUND)
if comment.user != user:
raise BaseCustomException(ErrorMessage.NOT_COMMENT_AUTHOR)
comment.delete()
디자인 도입
댓글


오늘의 문제
url 충돌
문제
원인
- 처음 작성한 URL 패턴이 완전하게 동일
- 따라서 댓글 수정을 위해 PUT /1/ 로 요청을 보내면, 장고는 첫 번째 줄인 <int:post_id>/ 패턴에 매칭
- CommentAPIView에는 et과 post 메서드만 존재하므로 PUT이나 PATCH 요청을 받으면
urlpatterns = [
path("<int:post_id>/", CommentAPIView.as_view(), name="comment_create"),
path("<int:comment_id>/", CommentManageAPIView.as_view(), name="comment_update"),
]