Django,React로 방명록 구현하기

김준영·2021년 2월 12일
0

저번에도 말했듯이 디자인 부분은 저도 못하기 떄문에 스킵하겠습니다.
우리가 해볼 방명록은 실시간 소통이 되는 카톡 형식이 아닌 내가 입력을 누르면 POST 요청이 Django로 들어가고 response가 오면 페이지를 reload 하는 형식으로 하려고 합니다. 사실 local에서 돌리면 이것도 빠릿빠릿 하게 되는데 heroku에 배포하면서부터 delay가 심한 것 같습니다. 이래서 AWS 쓰는구나..난 돈이 없지

1. 방명록 입력 구현하기.

방명록과 댓글 입력 구현하는 부분을 같이 짜겠습니다. Post 보여지는 부분에서 댓글 부분은 이런 식으로 짜면 되겠죠? 아니면 동일한 파일을 렌더링 해도 되고요.
먼저 input 3개가 필요합니다. 내 이름, 확인번호 ,내용을 입력할 댓글이 있어야 겠죠.


중간에 GuestCommentNameGuestCommentName GuestCommentName 는 함수 이름입니다. 저번에 Post 작성과 동일하게 react는 input에 useState로 접근시 focus를 잃는다고 하였습니다. 그래서 저는 Input을 처리하는 함수를 따로 만들어서 처리 하고 있습니다.(더 나은 방법이 있겠죠?)
데이터 전송을 위한 전역 변수

var data = {namedata:"none",
            checkdata:"none",
            bodydata:"none",
            my_id:"qkdaudfhrdkdlel",
}
var Toggle = {
    nametoggle:false,
    checktoggle:false
}

이름 Input

function GuestCommentName() {
    const [nameinput,SetNameInput] = useState({name:""})
    const {name} = nameinput
    const onChangename = e => {
        e.preventDefault()
        SetNameInput({
            name:e.target.value
        })
    }
    if(name.length===0) {
        Toggle.nametoggle=false
    }else {
        Toggle.nametoggle = true
        data.namedata=name
    }   
    return (
        <>
            <input
                className="input" 
                placeholder="이름을 입력하세요" 
                value={name}
                onChange={e=>onChangename(e)}
            />    
        </>
    )
}

확인 번호와 댓글 입력부분은 동일하게 하시면 됩니다.

2. 댓글 통신

우리는 저번에 Django로 통신하기 위해 Proxy 설정을 해주고(Cors 에러 회피) CSRF 토큰을 해제해 주었습니다.
이번에도 동일하게 react에서 통신을 보낼 준비를 하고 django 에서 통신을 받을 준비를 하겠습니다.

function SubmitGuestComment() {

    if(!Toggle.checktoggle || !Toggle.nametoggle) {
        console.log('No Data Here')
        alert("제목과 확인번호를 입력해주시기 바립니다.")
    }else {
   
        console.log('good to go')
        axios.defaults.xsrfCookieName = "csrftoken"
        axios.defaults.xsrfHeaderName = "X-CSRFToken"
        axios.post('/Comment/',{
            name:data.namedata,
            check:data.checkdata,
            body:data.bodydata,
            my_id:data.my_id
        }).then(function(response){
           
            if(response.data['response']==="Good") {
                //페이지 새로고침
                window.location.reload()

            }else {
                alert("오류가 발생하였습니다")
            }
        }).catch(function(error){
            console.log(error)  
        })
    }
}

react 코드를 보면 /comment로 통신을 보내고 있는거 보이시나요? 우린 django 에서 comment 받는 부분이 localhost:8000/comment 란 뜻입니다. django 코드를 작성하기위해 app을 하나 만들어 줍니다

django-admin startapp [앱이름:comment]

먼저 이 앱과 url 을 연동시켜야 겠죠? setting파일이 있는 urls.py에서

 path('Comment/', include('comment.urls')),

를 추가해 주고 comment폴더에서 urls.py 를 새로 생성해줍니다.
urls.py

from django.urls import path
from . import views


urlpatterns = [
    path('',views.commentPost, name='commentpost') 
]

views.py

@method_decorator(csrf_exempt,name='dispatch')
def commentPost(request):
    if request.method =="GET":
        return CommentListView.as_view()(request)
    elif request.method =="POST":
        req = json.loads(request.body.decode('utf-8'))
    
        name = req['name']
        check = req['check']
        body = req['body']
        my_id = req['my_id']
        if name!="None":
            print("comment 데이터를 정상적으로 입력받았습니다")
            commend= Comment(name=name,check=check,body=body,my_id=my_id)
            commend.save()
            return HttpResponse(simplejson.dumps({"response":"Good"}))
        else:
            print("comment 데이터를 찾을 수 없습니다")
            return HttpResponse(simplejson.dumps({"response":"Fail"})) 

저희가 주의깊게 볼건 views.py 인데요 . 지금 react에서 보내는 통신이 이름 ,확인번호, 내용 외에 하나가 더있지 않나요? my_id 라는 변수가 더 있습니다.
django model 에 id 필드가 있는데 이 멍청이는 아이디 값을 왜 넘기지? 라고 생각 하실 수 있습니다. 이렇게 되는 이유는 2가지가 있습니다.

1. comment 함수를 공유 하는가?

위에 말했듯 댓글 구현과 방명록 구현을 동일하게 처리한다고 했습니다. 그럼 django로 통신 오는 부분도 동일한 url로 오겠죠? 방금전에 /Comment로 통신했듯이. 일반 Post로 접속 했을때도 /Comment로 통신해서 django 의 이 함수로 오고 있습니다. 방명록 댓글과 일반 포스트 댓글을 구분하기 위한 기준은 있어야 겠죠.

def commentPost(request):

2. 관계형 데이터베이스를 쓰는가?

저번 포스트 에서 말했듯 documentDB를 쓰면 기준 그런거 안잡아도 됩니다.

이번 프로젝트의 딱 맞는 DB는 이런 식으로 구성이 될테니까요.

MySQL 구성은 이렇게 됩니다

형광펜 부분이 방명록으로 들어가는 Id 입니다. 딱봐도 비효율적이지않나요 (내가 비효율적으로 짠걸수도) 근데 왜 MySQL 을 쓰냐구요?? 공부 목적이니까요.

3. 댓글 불러오기

마지막에 django에 저장하는 함수를 구성했으니 바로 django 코드를 작업하겠습니다.
우리는 my_id를 기준으로 comment를 가져올겁니다.

@method_decorator(csrf_exempt,name='dispatch')
def fetchComment(request):
    if request.method=="GET":
        return CommentListView.as_view()(request)  
    elif request.method=="POST":
        req = json.loads(request.body.decode('utf-8'))
       
        my_id = req["my_id"]
        if Comment.objects.filter(my_id=my_id).exists():
         
            #쿼리셋을 json으로 바꿔준다
            my_response = list(Comment.objects.filter(my_id=my_id).values())
            #JsonResponse 한거랑 밑에 처럼 한거랑 똑같다.
           
            return HttpResponse(simplejson.dumps(my_response))
        else :
            return HttpResponse("N")

filter 함수를 통해 내가 원하는 comment를 가져와줍니다. 이때 가져오는 데이터 형식은 QuerySet 입니다. 그걸 json으로 보내주기 위해 simplejson 이란 모듈을 쓴거구요.
댓글이나 방명록이 불러와지는건 그 페이지에 접속하거나? 혹은 이 홈페이지 자체에 접속했을 때 데이터가 불러와져야 합니다. 저는 방명록 url로 접속시에만 댓글을 가져오도록 작업했습니다.

function GuestBook() {
    const dispatch = useDispatch()
    useEffect(()=> {
        fetch_myComment()
    },[])
    
    const fetch_myComment=()=> {
        axios.defaults.xsrfCookieName = "csrftoken"
        axios.defaults.xsrfHeaderName = "X-CSRFToken"
        axios.post('/Comment/fetchcomment',{
            my_id:data.my_id
        }).then(function(response){  
            if(!(response.data==="N")){
                //데이터 활용
           
            }else {
                //데이터 안올때
            }
        }).catch(function(error){
            console.log(error)
           
        })
    }
    return (

        <>
            <div className="wrapper">
                <HeaderSmall />
                <div className="guest-container">
                        <h1 className="guest-h1">
                            자유롭게 이야기를 나누는 공간입니다
                        </h1>
                    </div>
                    <div className="guest-body">
                        <div className="guest-write-comment">
                            <form className="form">
                                <div className="comment-header">
                                    <GuestCommentName/>
                                    <GuestCommentCheck/>
                                </div>    
                            </form>
                            <GuestCommentBody/>
                            <p className="iconp">
                                <AiOutlineSend className="sendicon" size="32" onClick={SubmitGuestComment}/>
                            </p>
  
                        </div>
                        <div className="guest-show-comment">
                            <ShowGuestComment/>
                        </div>
                    </div>
                </div>
            </div>
            
            
        </>
    )
}
    

GuestBook.js 는 방명록에 접속했을때 불러지는 함수인데요 useEffect를 통해 페이지가 렌더링 될 시 fetch_comment() 함수가 불려지죠?? 데이터가 온 것을 console.log()로 한번 확인해주면 끝입니다.

0개의 댓글