티스토리 뷰

리액트를 이용해서 장고의 템플릿을 대체하기

이번 포스팅에서 다룰 것은 리액트와 장고를 연결하는 것입니다. 장고의 템플릿 부분을 리액트로 대체하는 것이죠. 보통 이럴 경우 리액트 프로젝트를 eject 해서 바벨의 설정을 건드리지만 이 포스팅에서는 eject를 하지 않고 둘을 연결 시킨다음에 Oneline이라는 앱을 만들어 보려고 합니다. 


우선 eject를 하지 않는 이유는 리액트의 경우 이제 eject를 하지 않아도 sass를 적용시킬 수가 있습니다.(파일의 이름을 App.module.scss와 같은 형태로 바꿔주면 css 모듈과 sass가 둘다 적용됩니다.) 그래서 더더욱 꼭 eject를 할 필요가 있나 싶은 마음에 이번 포스팅을 준비했습니다.


우리가 만들 Oneline이라는 앱은 간단하게 쓴 글을 나타내는 앱입니다.


oneline 완성화면oneline의 완성 화면입니다.


장고와 리액트 모두 다뤄주고, 연결까지 시켜야하니 이번 포스팅은 매우 길어질 예정입니다. 중간 중간 활력소가 되는 커피를 마시면서 보시길 바랍니다.

장고 설치하기

우선은 프로젝트를 담을 디렉토리를 만들어 주세요. 저는 oneline이라는 프로젝트를 만들었습니다.

mkdir oneline
cd oneline


그리고 해당 디렉토리로 이동한 후 pipenv를 통해서 파이썬의 가상환경을 만들었습니다.


pipenv --three

pipenv shell


해당 명령어들을 커맨드에서 실행하면 파이썬3의 가상환경이 만들어지고 shell이라는 명령어를 통해서 실행됩니다.


현재 있는 디렉토리 위치 앞에 (oneLine-xxxxx)와 같은 형태가 붙어있다면 잘 따라하시고 있는 겁니다. 이제 해당 환경에서 장고를 다운로드 받아주세요.


pipenv install django

django startproject backend .


위와 같이 명령어를 입력했다면 (프로젝트를 설정할 수 있는)backend라는 폴더와 manage.py 파일이 생깁니다.


장고 설치장고 설치 후 프로젝트를 생성한 모습입니다.


oneline 앱 생성하기

이제 oneLine이라는 앱을 만들어보도록 하겠습니다.


python manage.py startapp oneLine


앱을 만들었으니 프로젝트의 backend/settings.py에 설정을 추가해보도록 하겠습니다.



기본적인 세팅은 끝났습니다. 이제는 슈퍼유저를 만들어줘야합니다.


python manage.py migrate

python manage.py createsuperuser


슈퍼유저까지 만들었나요? 에러없이 잘 작동하는 지 확인하시려면 python manage.py runserver 명령어를 입력하시고 "localhost:8000/admin" 접속해주세요. 에러가 없다면 이제는 모델과 어드민 파일을 다뤄줘야합니다.

모델과 어드민 파일 다뤄주기

우선은 oneLine/models.py 파일에 wisesaying이라는 클래스를 추가해주세요.


이제 wisesaying 클래스를 어드민 페이지에서도 확인할 수 있게 추가해줘야겠죠?



마이그레이션 해주는 것을 잊지마세요.

rest_framework 다루기

장고와 리액트를 연결한다는 것은 장고에서는 api를 제공해주고, 리액트는 그 api를 받아서 렌더링 해준다는 것을 의미합니다. 그러기 위해서는 일단 djangorestframework를 설치해야합니다.

pipenv install djangorestframework


설치하셨다면 backend/settings.py에 설치된 앱 부분에 'rest_framework'를 추가해주신 다음 oneLine/serializers.py 파일을 만들고 아래 내용을 추가해주세요.



시리얼라이저는 파이썬의 언어(파이썬의 클래스)를 브라우저가 이해할 수 있는 json 형식으로 바꿔준다고 생각하시면 됩니다.


이제 api를 제공해주는 뷰를 만들어야 합니다. oneLine/views.py에 다음 코드를 넣어주세요.



해당 뷰는 viewsets을 통해서 get, post, put, delete 의 기능을 제공해줍니다. 이제 뷰가 만들어졌으니 url을 만들어줄 차례죠?


backend/urls.py 파일 내부에 url을 넣어주도록 하겠습니다.



localhost:8000/api/wisesaying 에 접속하면 api를 볼 수 있습니다. rest_framework에서 제공하는 라우터를 통해서 해당 요청에 대한 url을 다 만들었습니다.


api 제공 페이지api를 제공하는 페이지입니다.


api/wisesaying에 접속하시면 위와 같이 api를 제공해주는 것을 볼 수 있습니다.

리액트 설치하기

리액트 설치는 cra를 통해서 간단하게 할 수 있습니다.

npx create-react-app frontend


해당 명령어를 커맨드를 통해 실행하면 frontend라는 폴더가 만들어집니다. 해당 폴더에서 필요없는 부분을 지워주세요.

(꼭 하실 필요는 없습니다.)



frontend/package.json에 프록시를 추가해주세요. 이렇게 설정해주는 이유는 개발 서버는 3000번 포트에서 이뤄지고, 사용자에게 보여지는 것은 8000번 포트이기 때문입니다. 그 둘을 구분하는 설정들을 해주는 것이죠. 하지만 api는 3000번 포트에 없고, 장고가 실행되고 있는 8000번 포트에 있습니다. 그래서 3000번 포트에서 찾지 못한다면 8000번 포트에서 찾으라고 알려주는 것입니다.

cors 다루기

이제는 장고에서 cors를 다뤄주어야 합니다. script 태그 내에서 다른 도메인 서버(+ 다른 포트)로 요청을 할 수 없는 것이 cors입니다. 우리는 3000포트에서 8000포트로 요청을 하는 것이니 이것을 해결해줘야 하죠.


pipenv install django-cors-headers


해당 모듈을 다운로드 하신 다음에 backend/settings.py 에 코드를 넣어주세요.



설정 밑에 화이트리스트를 추가하면 해당 도메인에서의 요청이 처리됩니다.

index 페이지 보여주기

개발은 3000번 포트, 보여지는 것은 8000번 포트라고 했었습니다. 일단은 거기에 맞는 설정을 해주도록 하겠습니다. 리액트 프로젝트내에서 yarn build 라는 명령어를 입력하면 build폴더가 만들어집니다. 그리고 압축되고 합쳐진 파일들이 이 빌드 폴더에 모이게 되죠. 장고에서 템플릿을 이 빌드 폴더에서 찾으라고 알려주면 우리가 개발한 페이지를 8000번 포트에서 볼 수 있습니다.


해당 코드들을 backend/settings.py 에 추가해주시면 됩니다. 템플릿 내부에 저렇게 적어주면 장고는 템플릿을 해당 위치에서 찾습니다. 즉 frontend/build 폴더에서 찾는 것이죠. 또 STATICFILES_DIRS에 적어준 값에서 static 폴더를 찾아서 적용시킵니다.


이제 장고와 리액트를 둘다 실행시키면 3천번 포트와 8천번 포트 모두에서 같은 화면을 볼 수 있습니다. 리액트에서 컴포넌트를 수정해보세요. 빌드하지 않았다면 3천번 포트와 8천번 포트의 보여지는 화면이 달라지게 되죠.

개발은 3000, 사용자에게 제공하는 건 8000! 멋지죠?

axios를 통한 데이터 처리 

이제는 axios를 통해서 http get,post, delete 요청을 수행해보도록 하겠습니다.


yarn add axios 


해당 모듈을 다운로드 한 다음에 src/TextItem.js 파일을 만들어주세요.



각 텍스트 아이템들을 나타내는 컴포넌트 입니다. 이제는 App.js의 코드를 교체해볼까요?



해당 코드들을 복사해서 붙여넣으시면 됩니다. axios를 통해서 간편하게 요청하실 수 있습니다. 중요한건 컴포넌트가 렌더링 된 다음 componentDidMount 메소드를 통해서 데이터를 가져옵니다. 데이터를 입력하시지 않았다면 admin 페이지로 가서 데이터를 입력해주세요.


axios.defaults.xsrfCookieName = "csrftoken";

axios.defaults.xsrfHeaderName = "X-CSRFToken"


다른 코드들 보다 해당 코드에 대한 설명부터 드려야 할 것 같습니다. 장고는 웹 사이트 공격 중의 하나인 CSRF에 대한 토큰 방식을 기본적으로 제공해줍니다. 장고의 템플릿에서 폼 데이터를 만들 때 {% csrf token %} 이라는 값을 적어주는 것으로 간단하게 처리할 수 있죠. 하지만 리액트를 통해서 템플릿을 하다보니 우리 입력창에는 토큰이 설정되어 있지 않아서 위의 두줄의 코드가 없다면 403을 반환합니다.


403 코드 반환해당 두줄을 제거하면 텍스트 전송 시 위와 같은 에러를 확인할 수 있습니다.


우리는 axios라는 모듈을 사용하기 때문에 간단하게 2줄로 처리할 수 있죠.


기본적으로 axios.get(url), axios.post(url, data), axios.delete(url/id)를 통해서 쉽게 http 요청을 할 수 있습니다. 아주 좋은 모듈이죠?



아주 길었지만, eject해서 바벨 설정을 건드리지 않고 리액트와 장고를 연결해봤습니다. 무언가 만들고 싶은 것이 생겻을 때 빨리 만들 수 있도록 도와주는 장고와 리액트를 합쳐보니 둘은 아주 궁합이 잘 맞는 사이(?) 라고 느껴지네요.



많이 길었지만 도움이 되는 포스팅이길 바랍니다. 공감은 제작자에게 큰 힘이 됩니다.


'Backend-dev > python' 카테고리의 다른 글

튜토리얼 배포하기(github, pythonanywhere)  (0) 2018.10.26
django에 css 부분 추가하기  (0) 2018.10.21
django의 template 작성하기  (0) 2018.10.21
views 파일에 class view 만들기  (0) 2018.10.20
djanog urls파일 만들기  (0) 2018.10.19
댓글