Django/view

[Python] 개월 수로 필터링

두잇 두두 2024. 3. 6. 21:45
728x90

배경

통계 페이지를 만들고 있는데 개월 별로 통계를 보여주려고 한다.

그런데 생각해보니 개월은 28~31까지 마지막 날이 다양하다. (대충 30일 마이너스 때리면 안된다는 이야기)

 

만들어야 하는 API 조건이 개월 별로 통계니까 정리하면

  1. request를 통해 param 받기
  2. 날짜로 형태 변환하기
  3. 날짜 만큼 형태 만들어주기
  4. db에서 들고온 데이터와 비교하기
  5. unique 해야 하기 때문에 중복제거를 해주기

벌써부터 머리 아프다

 

코드

1. request를 통해 param 받기, 2. 날짜로 형태 변환하기

start_date_str = request.GET.get('start_date', three_months_ago.strftime('%Y-%m-%d'))
end_date_str = request.GET.get('end_date', today.strftime('%Y-%m-%d'))

try:
    start_date = datetime.datetime.strptime(start_date_str, '%Y-%m-%d').date()
    end_date = datetime.datetime.strptime(end_date_str, '%Y-%m-%d').date()
except Exception:
    return get_400_error_response(
        'InvalidDateFormat',
        '날짜를 정확히 입력해주세요',
    )

 

3. 날짜 만큼 형태 만들어주기

date_list = []
review_list = []
date = start_date
date_difference = relativedelta(end_date, start_date)
total_months_difference = date_difference.years * 12 + date_difference.months + 1
for _ in range(total_months_difference):
    date_list.append(date.strftime('%Y-%m'))
    date = date + relativedelta(months=1)
    review_list.append([])

 

1년 이상 차이가 날 수 있기 때문에 years * 12를 해준다

 

4. db에서 들고온 데이터와 비교하기

for i in range(len(date_list)):
    if review.created_at.strftime('%Y-%m') == date_list[i]: 
        review_list[i].append(review)

 

5. unique 해야 하기 때문에 중복제거를 해주기

review_data={
    'label': '총 리뷰 데이터',
    'data': [len(set(review.place_id for review in data)) for data in review_list]
}

 

배운 점

쿼리에 filter해서 가져 올 수도 있지만 db 히트를 최대한 적게 하기 위해 데이터를 가져온 것을 python으로 비교해서 list안에 넣어주는 작업을 하였다. 이런 일은 그냥 아싸리 처음부터 list 만들어서 한땀한땀 비교해야지 라고 접근하는게 더 빠를 것 같다.

쿼리 잘 가져올려고 낑낑댔던 나야 고생했다,,