티스토리 뷰

728x90

목표

앞 글에서 말했다시피 가치 평가 서비스에서 가장 중요한 부분은 가치를 평가할 수 있어야한다는 것이다. 그래서 우리가 이번 멋쟁이 사자처럼 9기에서 배운 Django를 이용해 구현하려 했으나 멋사 선생님들께서 가치 평가할 때 마다 페이지를 새로고침하게 되면 (Django만을 사용하면 이렇게 밖에 구현이 안된다) 실제 구현된 일반 서비스들과는 다르고 또한 품질이 떨어지기 때문에 JS를 이용해서 만들어보라고 하셨다. 그래서 나의 목표는 ajax를 이용해 model의 DB를 수정하고 html에 표시하고 다시 DB에 저장하는 것이 나의 목표이다!!!

728x90

개발 예열

먼저 개발하기에 앞서 ajax는 무엇일까..

1학기 때 웹 프로그래밍 과목에서 js를 하면서 얼핏 들어본 기억이 난다. 처음 들었을 때 게임 리그오브레전드의 jax와 이름이 비슷해서 뇌리에 박힌 기억이 난다. 

 

ajax는  Asynchronous Javascript and XML의 약자로 비동기적으로 JS와 XML을 이용한 정보 교환 방법이다. 

 

굳이 왜 Django를 통해 구현하지 않고 ajax를 통해 구현하냐면 ajax는 페이지를 새로고침하지 않고도 데이터를 불러올 수 있기 때문에 사용자의 입장에서는 데이터를 불러올 때 마다 멀미나게 새로고침되는 페이지를 보지 않아도 된다. 따라서 우리가 가치 평가를 할 때 아주 적절한 기술이다.이번 프로젝트를 진행하면서 아직 깊이 ajax에 대해 공부한 것은 아니지만 얼추 사용하는 방법과 구글링을 통해 구현 문법 정도를 알게 되었다.

 

개발 시작

우선 ajax를 하기 전에 어떤 방식으로 Django가 굴러가는지 알아둘 필요가 있다.

Django는 아주 간단히 말해서 개발자가 url의 이름을 통해 view를 호출하여 함수를 사용하는 단계로 이뤄져있다. 따라서 먼저 사용할 함수를 작성하기 위해 html로 가서 요청 형식을 작성해줬다.

 

저기 보이는 {% csrf_token %} 이 거의 3일 동안 나를 괴롭혔는데 이 내용은 뒤쪽에 얘기하겠다. 간단하게 가치를 올리거나 내릴 수 있는 버튼과 model Item의 value를 직접 볼 수 있게 설정하였다. name에는 item의 id를 넣어 views.py에서 따로 보내지 않아도 되게끔 설정했다.

 

html에서 이제 view를 호출한다. 그래서 views.py로 가서 실행할 함수를 작성해줬다. 라는게 원래 Django의 순서이지만 우리가 이번에 진행할 것은 ajax이기 때문에 js를 먼저 작성해줘야한다. 내가 하고 있는 프로젝트의 베이스 기술 스택은 django이기 때문에 static/js 에 따로 파일을 저장한 후 python manage.py collectstatic 을 통해 적용시켜줘야한다. 

js에 내가 필요한 기능을 작성한 모습이다.

간략하게 설명해보자면 각 버튼이 눌렸을 시에 name에서 item의 id를 가져온다. 그래야 제품별로 가치를 다르게 측정할 수 있기 때문이다. 그리고 upValue를 설정하는데 올릴 때는 양수 1, 내릴 때는 음수 1로 설정하여 views.py 작성을 좀더 용이하게 할 수 있도록 했다.

이후 ajax를 작성하는데, url은 우리가 값을 보낼 주소, type은 통신 타입, data는 값 딕셔너리(파이썬이라서 딕셔너리다), success는 성공시 실행하는 영역을 의미한다.

나는 JmApp/detail/제품별 ID 이기 때문에 url에 pk를 지정해줬고 통신 타입은 POST, 보낼 데이터는 제품의 ID, 조정할 가치로 설정했다.

성공했을 시에는 console.log 를 통해 바로 볼 수 있게 하였고 response를 통해서 변경한 값을 받아와 html에 적용시킬 수 있게 하였다.

 

자, 이제 그럼 views.py 로 넘어가보자..

여기서 중요한 점은 if 문에서 조건이 2개라는 점이다. 내 detail.html에서는 그렇지 않지만 다른 곳에서는 method가 POST인 경우가 있을 수 있기 때문에 혼동을 방지하기 위해서 is_ajax()를 통해 ajax함수인지 한번더 확인하는 작업을 거쳤다.

먼저 내가 보낸 데이터 중 pk를 받아 제품ID를 통해 model Item에서 제품을 가져오고 value를 받아 변화시킬 값을 받아온다. 가치를 올리던지 내리던지 상관없이 앞에서 내릴 때는 -1로, 올릴 때는 1로 설정을 했기 때문에 int로 변화시켜 계산해주고 model DB에 저장시킨다. 이후 반환할 context에 딕셔너리 형태로 저장하고 HttpResponse를 통해 반환한다. 여기서 통신할 때 context는 json의 형태이기 때문에 이 형태를 해석하고 html에서 받아들을 수 있도록 json.dumps()를 사용해서 보내준다.

 

그럼 이제 마지막 부분인 url을 해야한다. 

근데 여기서 잠시만 이상한 생각이 든다. 아까 js에서 url을 설정할 때 JmApp/detail/제품ID로 값을 보낸다 했는데 굳이 url을 따로 써야하나 싶었다. 그리고 따로 쓴다해도 이것은 별로 좋지 않은 코딩이라 할 수 있겠다..

따라서 value 함수를 없애고 detail 함수에 합쳐서 작성했다. 그 결과가 다음 이미지이다.

저 clickCount는 내가 인기순, 즉 사용자들에게 클릭을 많이 당한 제품별로 정렬하기 위해 한 것이다. 그냥 저거 해낸게 뿌듯해서 그만..

이렇게 합쳐 놓으니 눈물이 날 것 같았다..

이왕 눈물 흘릴 거 작동 시키고 눈물 흘리기로 했다.

아직 아무것도 건들지 않은 상태이다

깨끗한 가치 0의 세번째 아이템을 선택해서 가치를 변경시켜보았다.

꺄아아아악

가치가 바뀌면서 콘솔 창에 성공했다고 출력된다. 그러면 DB에는 저장이 되었을까?

 

아주 정직하게 바뀌었다 ㅎㅎㅎㅎ

 

이번 목표 중 일어난 트러블슈팅

이번 목표는 얼핏 보면 금방 척척해낸 것 같지만 사실은 진짜 빌런은 따로 있었다. 

힘들었던 나날들..

Django는 원래 데이터를 보낼 때 csrf_token을 통해 값을 보호한다. 하지만 ajax를 통해 통신을 한다면 이것만으로는 부족하다. 하지만 그걸 몰랐던 나는 올바른 코드라고 생각되는 코드가 발생시키는 지속되는 오류 앞에 무너져내릴 수 밖에 없었다.

악랄한 빌런의 만행

그래서 이것만 거의 3일을 했다. 하지만 매우 간단하게도 해결책은 간단했다. Django 공식 홈페이지에도 적혀있듯이 그냥 아래 JS를 복사해서 붙여넣기만 하면 된다. 아래 코드는 ajax로 post 요청을 했을 시 csfr_token을 자동으로 생성하고 삽입하는 코드이다. 

여기까지만 하면 작동이 되는데 난 불안해서 추가적으로 구글링을 해서 다른 방법을 적용시켰다. 그 방법은 바로 csrf_exempt 데코레이터를 이용한 방식이었다. 

detail 함수에서 csrf 오류가 났기 때문에 csrf_exempt 데코레이터는 csrf_token 을 제외하고 통신을 할 수 있도록 설정하는 방법이다. 즉 csrf_token 오류가 날 수 있는 가능성을 제외한다는 것이다. 하지만 이 두 방법이 서로 충돌하면서 계속 같은 오류가 났었다. 결국 코드를 다시 짜면서 하나씩 적용시켜본 결과 해결되었다...^^...

둘 중 하나만 적용시켜도 훌륭하게 작동하는 코드를 붙잡고 괜한 시간을 쏟아부었다 생각하니 억울했다. 하지만 해결했으니 Okay입니다.

 

혹시나 나같은 실수를 하는 분들이 있다면 이 글을 읽고 조금이나마 도움이 되었으면 좋겠다.

 

참고 사이트(나를 구해주신 분들 ㅠㅠ) : https://jisun-rea.tistory.com/entry/Django-%EC%A2%8B%EC%95%84%EC%9A%94likes-%EA%B8%B0%EB%8A%A5-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0

 

[Django+Ajax/jQuery] '좋아요(likes)' 기능 구현하기 / 전체 웹페이지 새로고침 없이 좋아요 개수 업데이

참고 초보몽키의 개발공부로그 Many-to-many relationships stackoverflow: My own likes button 실습 저장소 https://github.com/JisunParkRea/djangotube_tutorial JisunParkRea/djangotube_tutorial Simple vid..

jisun-rea.tistory.com

https://jinmay.github.io/2019/04/09/django/django-ajax-csrf/

 

Django에서 ajax post 요청시 csrf token 문제 해결하기

Django에서 ajax 사용할때 발생하는 csrf 문제장고에서 ajax를 조금씩 섞어서 사용하다보면 POST 요청을 보낼때 문제가 발생하게 된다. POST 요청에서는 보안상의 문제로 csrf token을 필요로하게 되는게

jinmay.github.io

 

예고....?

아마 다음 목표는 내가 가치 평가한 물품들을 마이페이지에서 볼 수 있게끔 구현할 예정이다.

기능 로직은 내가 평가하는 순간 그 물품(Item)의 model에 있는 명단(userList)에 사용자 ID를 추가할 예정이다. 이후 마이페이지에서는 Item.object.all()을 통해 모두를 불러오고 filter 내장함수를 통해서 명단에 사용자 ID가 있는 물품의 ID만 마이페이지로 불러오게끔 할 예정이다. 이 기능은 Django만 사용하기 때문에 그렇게 어렵지 않을 것으로 예상된다 ㅎㅎ

728x90
300x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크