django annotate에 filter 적용하기

김형수·2023년 3월 9일
0

lichess 분석 기능 따라잡기

이전에 포스팅했던 새로운 방식으로 코드를 변경했다.

@api.get('/moveline')
def get_moveline(request, moves: str = None):
    board = chess.Board()
    if moves == None:
        data = list(ChessNotation.objects.annotate(submoves=Substr('mainline', 1, 4)).exclude(mainline='').values('submoves').annotate(cnt=Count('submoves'), white_win=Count(
            'result', filter=Q(result__iexact='white')), draw=Count('result', filter=Q(result__iexact='draw')), black_win=Count('result', filter=Q(result__iexact='black'))).order_by('-cnt'))

        return JsonResponse(data, safe=False)
    else:
        move = moves.split(',')
        data = list(ChessNotation.objects.filter(mainline__startswith=moves).exclude(mainline=moves).annotate(submoves=Substr(
            'mainline', 1+5*len(move), 4)).values('submoves').annotate(cnt=Count('submoves'), white_win=Count(
                'result', filter=Q(result__iexact='white')), draw=Count('result', filter=Q(result__iexact='draw')), black_win=Count('result', filter=Q(result__iexact='black'))).order_by('-cnt'))
        return JsonResponse(data, safe=False)

orm이 기존에비해 많이 길어지긴 했지만, 속도측면이나 데이터베이스 용량측면에서 보다 나아졌다고 확신한다.

다중 annotate 조건

django annotate를 사용할때 조건을 적용할 수 있다.

ChessNotation.objects.filter(mainline__startswith=moves).exclude(mainline=moves).annotate(submoves=Substr(
            'mainline', 1+5*len(move), 4)).values('submoves').annotate(cnt=Count('submoves'), white_win=Count(
                'result', filter=Q(result__iexact='white')), draw=Count('result', filter=Q(result__iexact='draw')), black_win=Count('result', filter=Q(result__iexact='black'))).order_by('-cnt'))

0개의 댓글