[Django] 필드 값별 객체 개수 반환하기 (감정표현 개수 반환)

채린·2023년 9월 1일


감정표현Emotion의 필드 content는 1,2,3,4,5중 하나이며 댓글처럼, 한 유저가 하나 생성하면 Emotion객체 하나가 생성된다.(1, 'happy'),(2, 'surprise'),(3, 'angry'),(4, 'sad'),(5, 'serious')
화면에서는 감정별로 그 개수만 필요하니 이를 만들어보자

시리얼라이저에 Emotion필드가 있고 : Emotion =serializers.SerializerMethodField()
아래에 이를 직접 커스터마이징 해보자

결과:

def get_Emotion(self, instance):
        request = self.context.get('request')
        line_id = instance.line_id
        
        # 해당 Line에 연결된 Emotion 중에서 content별로 사용자 수를 계산
        emotion_counts = Emotion.objects.filter(emo_line_id=line_id).values('content').annotate(num=Count('emo_id'))
        
        # content 순서에 따라 결과를 만들기 위해 딕셔너리로 변환
        emotion_count_dict = {item['content']: item['num'] for item in emotion_counts}
        
        # 모든 content에 대해 결과를 생성하며, 없으면 기본값인 0 사용
        result = [
            {'content': content, 'num': emotion_count_dict.get(content, 0)}
            for content in range(1, 6)  # content는 1부터 5까지의 숫자
        ]
        # 만든 데이터들을 EmotionCountSerializer에 넣어 반환
        return EmotionCountSerializer(result, many=True, context={'request': request, 'line': line_id}).data

이때 리턴하는 EmotionCountSerializer에서는 is_my로 현재 사용자가 이 감정표현을 했는지 정보를 더해준다.

class EmotionCountSerializer(serializers.Serializer):
    content = serializers.IntegerField()
    num = serializers.IntegerField()
    is_my = serializers.SerializerMethodField()
    def get_is_my(self, obj):
        request = self.context.get('request')
        line=self.context.get('line')
        user=request.user
        if request and request.user.is_authenticated:
            if Emotion.objects.filter(content=obj['content'], emo_user=user,emo_line=line).exists():
                return True
            else:
                return False
        return False

결과:

"Emotion": [          
	{
    	"content":1,
		"num": 2,
		"is_my": true
	},
	{
		"content":2,
		"num": 0,
		"is_my": false
	},
	{
		"content":3,
		"num": 1,
        "is_my": false
	,
	{
		"content":4,
		"num": 0,
		"is_my": false
	},
	{
	"content":5,
	"num": 1,
	"is_my": true
    }
]

0개의 댓글