본문 바로가기
🖥Web/🔥Django

[Django] 초급 React + Django 간단한 익명 블로그 만들기 8

by 후누스 토르발즈 2021. 11. 26.
반응형

 

 

 

 

 

 

react-modal 설치, ajax 응답 성공/실패 핸들링, 백엔드 새로운 model 생성하여 insert

 

react에서 인서트 할 수 있는 모달화면을 정의하고 응답에 따라 핸들링 하겠습니다.

 

 

 

 

일단 npm install react-modal을 사용하여 패키지를 내려받습니다.

 

 

 

 

Home.js

import React, { useState } from 'react';
import '../pages_css/Home.css';
import BoardModal from './BoardModal';

const Home = () => {
  const [modal_is_open, setModalIsOpen] = useState(false);
  return (
    <div className="parentDiv">
      <h1 className="sectionTitle">Home</h1>
      <div className="buttonDiv">
        <button className="goodButton" onClick={() => setModalIsOpen(true)}>
          NEW
        </button>
      </div>
      <BoardModal modal_is_open={modal_is_open} setModalIsOpen={setModalIsOpen} />
    </div>
  );
};
export default Home;

 

 

 

 

/pages_css 라는 폴더를 만들어서 Home.css 파일을 만들어 줍니다.

.parentDiv {
  padding: 60px;
}

.sectionTitle {
  font-size: 62px;
  font-weight: bold;
  padding: 30px;
}

.buttonDiv {
  width: 92%;
  text-align: right;
}

.goodButton {
  margin: 10px;
  width: 90px;
  font-size: 20px;
  height: 40px;
  border-radius: 4px;
  color: white;
  background-color: rebeccapurple;
}

.modal {
  position: fixed;
  height: 400px;
  min-width: 600px;
  top: 20%;
  left: 30%;
  border: 2px solid rebeccapurple;
  border-radius: 2px;
  background: white;
}

 

 

 

 

 

pages/BoardModal.js 파일을 생성합니다.

import React, { useState } from 'react';
import Modal from 'react-modal';
import '../pages_css/BoardModal.css';
import axios from 'axios';

const BoardModal = (data) => {
  const [title, setTitle] = useState('');
  const [content, setContent] = useState('');
  const [writer, setWriter] = useState('');
  const [password, setPassword] = useState('');

  const crypto = require('crypto');

  const insertBoardValueCheck = () => {
    if (title === '') {
      alert('Please input title');
      return false;
    }
    if (content === '') {
      alert('Please input content');
      return false;
    }
    if (writer === '') {
      alert('Please input writer');
      return false;
    }
    if (password === '') {
      alert('Please input password');
      return false;
    }
    return true;
  };

  // 게시글 등록
  const insertBoard = async () => {
    console.log('insertBoard');
    if (!insertBoardValueCheck()) return;
    const headers = {
      'Content-type': 'application/json; charset=utf-8;',
      Accept: 'application/json',
    };
    const datas = {
      board_seq: null,
      board_title: title,
      board_content: content,
      board_writer: writer,
      board_password: crypto
        .createHmac('sha256', 'anonymous_blog_key')
        .update(password)
        .digest('hex'),
    };
    axios
      .post('http://127.0.0.1:8000/insertBoard/', datas, {
        headers,
      })
      .then((response) => {
        if (response.data.response_code) {
          data.setModalIsOpen(false);
        } else {
          alert(response.data.messege);
        }
      })
      .catch((response) => {
        alert(response.data.messege);
      });
  };

  return (
    <Modal className="modal" isOpen={data.modal_is_open} ariaHideApp={false}>
      <div style={{ height: '100%' }}>
        <h1 className="sectionTitle">Write</h1>
        <div style={{ paddingLeft: '4%', paddingRight: '4%' }}>
          <h1 style={{ fontSize: 28, fontWeight: 'bold' }}>Title</h1>
          <input
            className="inputs"
            onChange={(e) => setTitle(e.target.value)}
          />
          <h1 style={{ fontSize: 28, fontWeight: 'bold', marginTop: 10 }}>
            Content
          </h1>
          <textarea
            rows={4}
            className="inputs"
            onChange={(e) => setContent(e.target.value)}
            style={{ resize: 'none' }}
          />
          <div className="buttonDiv">
            <input
              placeholder="writer"
              onChange={(e) => setWriter(e.target.value)}
              style={{
                padding: 6,
                width: 200,
                fontSize: 20,
                resize: 'none',
                marginRight: 20,
                borderRadius: 4,
              }}
            />
            <input
              placeholder="password"
              type="password"
              onChange={(e) => setPassword(e.target.value)}
              style={{
                padding: 6,
                width: 200,
                fontSize: 20,
                resize: 'none',
                borderRadius: 4,
              }}
            />
            <button className="goodButton" onClick={() => insertBoard()}>
              SAVE
            </button>
            <button
              className="badButton"
              onClick={() => data.setModalIsOpen(false)}
            >
              CLOSE
            </button>
          </div>
        </div>
      </div>
    </Modal>
  );
};
export default BoardModal;

암호화하는 부분은 설명 생략하겠습니다.

 

 

 

 

BoardModal.css

.sectionTitle {
    font-size: 62px;
    font-weight: bold;
    padding: 30px;
}

.inputs{
    width: 92%;
    padding:8px;
    font-size:22px, 
}

.buttonDiv {
    width:92%;
    text-align: right;
}


.goodButton {
    margin: 10px;
    width: 90px;
    font-size: 20px;
    height: 40px;
    border-radius: 4px;
    color: white;
    background-color: rebeccapurple;
}

.badButton {
    margin-top: 10px;
    width: 90px;
    font-size: 20px;
    height: 40px;
    border-radius: 4px;
    color: white;
    background-color: red;
}

 

 

 

 

 

위 코드 작성시 볼 수 있는 화면입니다.

 

 

 

views.py

# rest
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.parsers import JSONParser
import json

from anonymous_blog_server.utils.board import insert_utils_board


# 게시글 등록
@csrf_exempt
def insert_board(request):
    data = json.loads(request.body)
    return JsonResponse(
        data=insert_utils_board(
            board_seq=data.get('board_seq', None),
            board_title=data.get('board_title', None),
            board_content=data.get('board_content', None),
            board_writer=data.get('board_writer', None),
            board_password=data.get('board_password', None)
        )
    )

 

 

 

 

utils.py

# from django.db import models
from core import models
import traceback


# 게시글 등록
def insert_utils_board(
    board_seq=None,
    board_title=None,
    board_content=None,
    board_writer=None,
    board_password=None,
):
    try:
        if not board_title:
            return {
                'response_code': False,
                'messege': '게시판 제목을 받지 못하였습니다.'
            }
        if not board_content:
            return {
                'response_code': False,
                'messege': '게시판 내용을 받지 못하였습니다.'
            }
        if not board_writer:
            return {
                'response_code': False,
                'messege': '익명 제목을 받지 못하였습니다.'
            }
        if not board_password:
            return {
                'response_code': False,
                'messege': '익명 패스워드를 받지 못하였습니다.'
            }
        if board_seq:
            pass
        else:
            seq = None
            try:
                seq = models.TbBoard.objects.latest('board_seq').board_seq + 1
            except models.TbBoard.DoesNotExist:
                seq = 1
            tb_board = models.TbBoard()
            tb_board.board_seq = seq
            tb_board.board_title = board_title
            tb_board.board_content = board_content
            tb_board.board_writer = board_writer
            tb_board.board_password = board_password
            tb_board.save()
        return {
            'response_code': True,
            'messege': '게시글이 저장되었습니다.'
        }
    except Exception:
        print(traceback.format_exc())
        return {
            'response_code': False,
            'messege': '서버 에러'
        }

 

 

if board_seq:

    pass

부분은 <table>을 만든 후 만들겠습니다.

 

 

 

urls.py

from django.contrib import admin
from django.urls import path
from .views.about import get_views_about
from .views.board import insert_board

urlpatterns = [
    path('about/', get_views_about),
    path('insertBoard/', insert_board),
]

 

 

 

settings.py의 TIME_ZONE를 'Asis/Seoul' 로 변경하고 USE_TZ 를 False로 바꿔줍니다.

TIME_ZONE = 'Asia/Seoul'
USE_TZ = False

 

 

 

 

제목, 내용, 작성자, 패스워드를 입력하요 저장을 누릅니다.

 

 

 

저장시에 성공인경우 정상응답을 받은 경우 홈화면이 보여야하며

 

 

 

 

실패시에는 alert이 보여야하며 확인을 눌러도 홈화면으로 이동하지않고 모달이 그대로 남아있어야 합니다

 

 

 

 

db에서 조회시 값이 들어가 있어야 정상입니다.

 

 

 

이렇게까지 react-modal 설치, ajax 응답 성공/실패 핸들링, 백엔드 새로운 model 생성하여 insert 하였습니다.

 

 

 

 

반응형