Django-mysite만들기9 게시판 조회수 중복 증가 쿠키 처리
25 Jun 2019 | django python django-ormdjango mini project
cafe24신입사원 교육과정 - django 수업 내용 정리
쿠키를 이용해서 조회수 중복 증가 막기
이전에 작성한 포스팅에서 글 상세보기를 눌렀을 때, 조회수 증가 처리를 아래의 코드와 같이 간단하게 +1처리만 했었는데,
def view(request, no=0):
    if no == 0: return HttpResponseRedirect('list')
    board = Board.objects.filter(id=no)
    board.update(hit=F('hit')+1)
    data = {
        'board':board[0]
    }
    return render(request, 'board/view.html', data)
이 코드의 경우 F5를 누르면 계속해서 조회수가 +1씩 증가하게 된다.
이를 위해서 쿠키를 이용해서 조회수 중복 증가를 조금이나마 막는 코드로 수정했다.
Python Cookie 만드는 법
[ 쿠키 만들기 ]
set_cookie(name, value, max_age)
name: 쿠키 이름value : 저장하는 값
max_age : 쿠키 유지 시간
위의 코드로 쿠키를 만들어 심을 수 있다.
[ 쿠키 읽기]
request.COOKIES.get(쿠키이름) : 쿠키 데이터를 문자열로 반환해준다.
[ 쿠키 삭제]
response = render(request, 해당 template, data)
response.delete_cookie(쿠키이름)
조회수 코드 수정하기
로그인 한 경우 쿠키 이름을 hit:로그인유저id 로,  로그인 안한 경우 hit로 설정할 예정이다. 각각의 쿠키의 값으로는 게시글 번호를 |와 함께 값을 이어 붙일 예정이다.
쿠키는 매일 자정 12시에 reset 시킬 것이다.
ex) ‘쿠키이름=쿠키값(방문 게시글 목록)’
35번 회원이 로그인 한 경우  : hit:35=57|56|54|47|32|58|59
로그인 안한 경우				    : hit=57|56|54|47|32|58|59
Python 쿠키 특정 정해놓은 시간에 삭제하는 법
쿠키는 매일 자정 12시에 reset 시킬 것이다.
tomorrow = datetime.datetime.replace(datetime.datetime.now(), hour=23, minute=59, second=0)
expires = datetime.datetime.strftime(tomorrow, "%a, %d-%b-%Y %H:%M:%S GMT")
...
response.set_cookie(쿠키이름, 쿠키값, expires =expires)
코드
def view(request, no=0):
    # 존재하는 게시글이 없을 경우 return
    if no == 0:
        return HttpResponseRedirect('list')
    # template에 전달할 데이터
    board = Board.objects.filter(id=no)
    data = {
        'board':board[0]
    }
    
    response = render(request, 'board/view.html', data)
    # [1] 로그인 확인
    if request.session.get('authUser') is None:
        cookie_name = 'hit'
    else:
        cookie_name = f'hit:{request.session["authUser"]["id"]}'
    # [2] 그 날 당일 밤 12시에 쿠키 삭제
    tomorrow = datetime.datetime.replace(datetime.datetime.now(), hour=23, minute=59, second=0)
    expires = datetime.datetime.strftime(tomorrow, "%a, %d-%b-%Y %H:%M:%S GMT")
    # [3] hit를 check하는 쿠키가 있는 경우
    if request.COOKIES.get(cookie_name) is not None:
        cookies = request.COOKIES.get(cookie_name)
        cookies_list = cookies.split('|')
        if str(no) not in cookies_list:
            response.set_cookie(cookie_name, cookies + f'|{no}', expires =expires)
            board.update(hit=F('hit') + 1)
            return response
    # [4] hit를 check하는 쿠키가 없는 경우
    else:
        response.set_cookie(cookie_name, no, expires =expires)
        board.update(hit=F('hit') + 1)
        return response
    return render(request, 'board/view.html', data)
해당하는 쿠키(str)에 |를 기준으로 계속 이어 붙여주는 형식으로 작성했다.
NetWork 탭에서 확인해보면 아래의 그림과 같이 쿠키가 담기는 것을 확인할 수 있다.
하지만 이 코드 역시 브라우저의 쿠키 삭제 후 다시 게시글에 방문하면 조회수가 증가하게 된다…
        
              콩정의 개발 정리 블로그