content
필드에 데이터가 저장되지 않는 문제와 블러 처리 구현새 리뷰를 생성할 때, POST
요청에 포함된 content
값이 데이터베이스에 저장되지 않는 문제가 발생했습니다. 이와 동시에 차단된 사용자의 리뷰를 조회할 때 내용을 블러 처리하는 기능을 구현하려고 했습니다. 하지만 두 기능이 충돌하면서 아래와 같은 문제가 발생했습니다:
content
필드가 SerializerMethodField
로 설정되어 있었습니다.SerializerMethodField
는 읽기 전용 필드로, 요청 데이터를 받아들이지 않기 때문에 새 리뷰 생성 시 content
값이 무시되었습니다.content
필드와 연결되어 리뷰 생성과 조회 기능 간의 혼란이 발생했습니다.content
필드가 저장되지 않아 블러 처리 이전에 기본 동작부터 실패했습니다.SerializerMethodField
의 읽기 전용 특성
SerializerMethodField
는 데이터를 직렬화할 때 get_<field_name>
메서드의 반환값만 사용하며, 모델 필드와 연결되지 않습니다.POST
요청에서 content
데이터를 저장하지 못했습니다.블러 처리와 데이터 저장의 충돌
content
필드를 블러 처리 로직과 동일하게 처리하려다 보니, 읽기와 쓰기가 충돌했습니다.읽기와 쓰기를 분리
content
필드는 데이터 저장용으로 유지하고, 차단된 사용자 리뷰를 숨김 처리하는 블러 처리 로직은 content_display
라는 추가 필드로 분리했습니다.content
: 원본 리뷰 데이터를 저장하고 반환.content_display
: 차단된 사용자의 리뷰 내용을 숨김 처리하여 반환.직렬화 및 로직 구현
content_display
는 SerializerMethodField
를 사용하여 읽기 전용으로 설정.content
는 모델 필드와 연결하여 리뷰 생성 시 데이터를 저장.1. ReviewSerializer
class ReviewSerializer(serializers.ModelSerializer):
"""Review 모델 직렬화"""
nickname = serializers.SerializerMethodField() # 사용자 닉네임 반환
content_display = serializers.SerializerMethodField() # 차단된 사용자 콘텐츠 처리
comments = ReviewCommentSerializer(many=True, read_only=True) # 연결된 댓글들
total_likes = serializers.IntegerField(read_only=True) # annotate로 계산된 값
total_dislikes = serializers.IntegerField(read_only=True) # annotate로 계산된 값
game_name = serializers.CharField(read_only=True)
header_image = serializers.CharField(read_only=True)
class Meta:
model = Review
fields = [
'id', 'user', 'nickname', 'content', 'content_display', 'app_id', 'game_name', 'header_image', 'score', 'categories',
'created_at', 'updated_at', 'comments', 'total_likes', 'total_dislikes'
]
read_only_fields = [
'id', 'created_at', 'updated_at', 'comments', 'total_likes', 'total_dislikes', 'game_name', 'header_image', 'categories', 'content_display'
]
def get_nickname(self, obj):
"""유저 닉네임 반환 (유저가 없으면 '알수없음')"""
return obj.user.nickname if obj.user else "알수없음"
def get_content_display(self, obj):
blocked_users = self.context.get('blocked_users', [])
if obj.user and obj.user.id in blocked_users:
return "이 사용자의 리뷰는 차단되어 표시되지 않습니다."
return obj.content
2. ReviewDetailAPIView
class ReviewDetailAPIView(APIView):
def get(self, request, pk):
"""특정 리뷰 조회"""
review = get_object_or_404(Review, pk=pk)
blocked_users = Block.objects.filter(blocker=request.user).values_list('blocked_user', flat=True) if request.user.is_authenticated else []
serializer = ReviewSerializer(review, context={'blocked_users': list(blocked_users)})
return Response(serializer.data, status=status.HTTP_200_OK)
리뷰 생성 시 content
저장 정상화
POST
요청 시 content
데이터가 Review
모델에 정상적으로 저장됩니다.블러 처리 기능 분리
content_display
필드가 차단된 사용자의 리뷰를 숨김 처리하여 반환합니다.content
)는 변경되지 않고, 필요할 때 블러 처리 로직만 동작합니다.코드의 명확성과 확장성 증가