[리액트react] async 리액트에서 장고 API 요청해서 자료 받아오기(GET)

업데이트:

리액트(react) async 장고 API 서버에 요청해서 자료 받아오기(GET)

참고링크

운영체제 프론트엔드 백엔드 데이터베이스 인프라
리눅스구조 js필터 아파치에러로그 행삭제 아파치스쿱
프로세스 헬로월드 웹서버개념 ES기초 로그분석
네임스페이스 프로젝트생성 아파치설치 MySQL기초 beeline
디렉토리 헤더생성 flask연동 큐브리드 하둡기초
리다이렉션 async-get 장고MsSQL연결 null공백 나이파이
쓰레드 async-post 장고MySQL연결 MySQL설치(win) 백본
라즈베리파이설치 로그인페이지 장고inpectdb MySQL테이블생성 제플린
OSI7계층소개   장고read   SSL인증
OSI1계층   장고insert   커버로스
OSI2계층   장고put   도커개념
OSI3계층   장고del   도커설치
OSI4계층   flask한글요청   도커기초
OSI5,6,7계층       도커이미지
DNS서버       컨테이너네트워크
DHCP       도커API
bashrc       도커컴포즈
bash       도커볼륨
ifconfig       장고이미지
소켓프로그래밍       도커postgre
리눅스유저생성       도커이미지삭제
netstat포트열기       도커Redis
컴파일러       k8s구조
운영체제vs커널       k8s설치
작업스케쥴링       k8s서비스배포
디스크추가       POD네트워크
aws유저추가       퍼시스턴트볼륨
기초명령어       k8s에러
포트번호        

참고 링크

DB

백엔드

프론트엔드

1. 사전 준비 사항

지금부터 만들 앱은 파이썬 장고(django)에 연동할 프론트를 리액트로 만드는 실습입니다. 본 포스팅은 이전 포스팅에서 이어지는 포스팅 입니다.

이번 실습에서 axios를 사용하기 위해 axios를 설치해주겠습니다. axios를 활용하면 GET, PUT, POST, DELETE와 같은 API 요청이 가능합니다.

$ cd myapp01
$ npm add axios

added 2 packages, and audited 1438 packages in 3s

191 packages are looking for funding
  run `npm fund` for details

6 high severity vulnerabilities

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

2. 장고 API 서버 가동

인텔리제이를 실행하고 이전 포스팅에서 만들었던 장고 API(dbcontest 프로젝트)를 가동시킵니다.

dbcontest$  python manage.py runserver

Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
June 14, 2022 - 09:42:58
Django version 4.0.2, using settings 'dbcontest.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

실제 개발 화면은 다음과 같습니다.

그리고 웹 브라우저를 열고 다음 url로 접근해봅니다.

‘http://127.0.0.1:8000/test/test01data/Cheolwon’

그러면 다음 화면이 나옵니다.

따라서 지금부터는 위 스크린샷에 나오는 자료를 리액트로 요청해서 받아서 처리해보겠습니다. 실습을 하는 동안 장고 서버는 내리지 말아주세요. 우리가 받아와야 실습을 하는 동안 장고 서버는 내리지 말아주세요.

{
    "id": 1,
    "name": "Cheolwon",
    "email": "abcd@email.com",
    "created_at": "2022-05-30T20:25:49Z",
    "updated_at": null
}

3. src/pages/Find.js 파일 수정

기존에는 다음과 같았던 src/pages/Find.js 파일을….

const Find = () => {
  return(
    <div>
      <h1>친구찾기</h1>
      <p>보고싶은 친구를 찾아보아요</p>
    </div>
  );
};

export default Find;

다음과 같이 수정하겠습니다.

import React, {useState} from 'react';
import axios from 'axios';

const Find = () => {
  const [data, setData] = useState(null);
  const onClick = async () => {
    try{
      const response = await axios.get(
        'http://127.0.0.1:8000/test/test01data/Cheolwon',
      );
      setData(response.data);
    } catch (e) {
      console.log(e)
    }
  };

  return(
    <div>
      <h1>친구찾기</h1>
      <p>보고싶은 친구를 찾아보아요</p>
      <button onClick={onClick}>불러오기</button>
      {data && <textarea rows={15} value={JSON.stringify(data, null, 2)} readOnly={true}/>}
    </div>
  );
};

export default Find;

그리고나서 리액트를 실행하고 버튼을 눌러보면 다음과 같은 접근 권한 에러가 나는 것을 알 수 있습니다.

4. 장고 접근 권한 해결

4.1. django-cors-headers 설치

장고에서 리액트 요청을 받을 수 있도록 장고 프로젝트를 수정해보겠습니다. 먼저 장고를 프로젝트를 열고 다음을 설치합니다.

$ pip install django-cors-headers

그리고 dbcontest/settings.py 파일을 다음과 같이 수정합니다.

4.2. dbcontest/settings.py 수정

dbcontest/settings.py 파일에서 INSTALLED_APPS에서 'corsheaders',를 추가합니다.

 INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'test01',
    'rest_framework',
    'corsheaders',
]

그리고 MIDDLEWARE에 다음 두줄을 추가합니다.

'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',

그러면 MIDDLEWARE은 다음과 같이 됩니다. 미들웨어에 추가할 때는 corsheaders는 가급적 위에 있어야 합니다.

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',

    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

그리고 특정 클라이언트로부터 요청을 받을 수 있게 CORS_ALLOWED_ORIGINS을 작성합니다. CORS_ALLOWED_ORIGINS는 원래는 없으므로 파일 가장 하단에 다음과 같이 만들어줍니다.

CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",
    "http://127.0.0.1:3000"
]

참고로 만약 모든 클라이언트로부터 접근을 허용하고 싶다면 다음 코드를 추가합니다.

CORS_ALLOW_ALL_ORIGINS = True

5. 다시 리액트로 확인

다시 웹 브라우저에서 다음 리액트 앱에 접근합니다.

‘http://localhost:3000/find’

그리고 불러오기를 누르면 다음과 같은 화면이 출력됩니다.

6. 좀 더 예쁘게 가져오기

이전에는 텍스트 영역에 json 내용을 통째로 넣었는데 이번에는 좀 더 예쁘게 넣어보겠습니다.

src/pages/Find.js 파일을 다음과 같이 수정합니다.

import React, {useState} from 'react';
import axios from 'axios';

const Find = () => {
  const [data, setData] = useState(null);
  const onClick = async () => {
    try{
      const response = await axios.get(
        'http://127.0.0.1:8000/test/test01data/Cheolwon',
      );
      setData(response.data);
    } catch (e) {
      console.log(e)
    }
  };

  return(
    <div>
      <h1>친구찾기</h1>
      <p>보고싶은 친구를 찾아보아요</p>
      <button onClick={onClick}>불러오기</button>
      {data && <textarea rows={15} value={JSON.stringify(data, null, 2)} readOnly={true}/>}
      <br /><br /><br />

      <button onClick={onClick}>예쁘게 불러오기</button>
      <br /><br />
      {data && <li>{JSON.stringify(data, ['id', 'name', 'email'], 2)}</li>}
      {data && <li>{JSON.stringify(data, ['id'], 2)}</li>}
      {data && <li>{JSON.stringify(data, ['name'], 2)}</li>}
      {data && <li>{JSON.stringify(data, ['email'], 2)}</li>}
      {data && <li>id: {data.id}</li>}
      {data && <li>name: {data.name}</li>}
      {data && <li>email: {data.email}</li>}
    </div>
  );
};

export default Find;

이는 화면으로 보면 다음과 같습니다.

그리고 웹 브라우저에서 ‘예쁘게 불러오기’를 클릭하면 다음과 같습니다.