본문 바로가기
my_lesson/_Python

Python - Django ReactJS project

by boolean 2019. 7. 24.
728x90

Python - Django ReactJS project


선수 조건

cnoda가상환경 설치 [바로가기]

Python 설치 [운영체제 직접설치 바로가기(비추천)]  [가상환경 설치 바로가기(추천)]

django 설치 [바로가기]

NodeJS 설치 [바로가기] 

NPM NodeJS 설치시 자동설치

Yarn 설치 [바로가기]

create-react-app 설치 [바로가기]



이 글의 Project 의존성 버전


(conPython37) F:\project\PYTHON\deact>conda -V
conda 4.6.14

(conPython37) F:\project\PYTHON\deact>python --version
Python 3.7.3

(conPython37) F:\project\PYTHON\deact>node -v
v10.16.0

(conPython37) F:\project\PYTHON\deact>npm -v
6.10.2

(conPython37) F:\project\PYTHON\deact>yarn -v
1.17.3

주의사항

회색 은 주석입니다

녹색은 경로입니다.

검정색은 명령어입니다.

.(마침표) ,(쉼표) '(홑따옴표) "(쌍따옴표)  (공백) 주의 하세요.




1. Create React App 


 F:\project\PYTHON>yarn create react-app deact /EDIT 2020.01.19

 F:\project\PYTHON>cd deact

 F:\project\PYTHON\deact>yarn start   처읔 실행할 때 렌더링 시간 때문에 오래 걸림


issue : A template was not provided create-react-app 

새로운 cmd 창을 열고 가상환경으로 진입합니다.

아래와 같은 경로에서 django project 를 만드는데 deactBackend .(마침표)를 확인하세요.

.을 잊지 말고 새로운 폴더가 아닌 현재 디렉토리에서 프로젝트를 생성할 수 있게 합시다.


2.Embeded Create Django Project


F:\project\PYTHON\deact>conda activate conPython37

(conPython37) F:\project\PYTHON\deact>django-admin startproject deactBackend .

app 추가

(conPython37) F:\project\PYTHON\deact>python manage.py startapp post

app 초기화

(conPython37) F:\project\PYTHON\deact>python manage.py migrate

DB를 따로 설정할 수도 있다[바로가기]  기본값은 sqllite3이다.


#(conPython37) F:\project\PYTHON\deact/deactBackend/settings.py>
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

'post',#추가
]




#(conPython37) F:\project\PYTHON\deact/post/models.py>
from django.db import models

# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=20)
contents = models.TextField()

def __str__(self):
"""Representation of the model as string. """
return self.title



#(conPython37) F:\project\PYTHON\deact/post/admin.py>
from django.contrib import admin
from .models import Post
# Register your models here.

admin.site.register(Post)


(conPython37) F:\project\PYTHON\deact>python manage.py makemigrations

(conPython37) F:\project\PYTHON\deact>python manage.py migrate

(conPython37) F:\project\PYTHON\deact>python manage.py createsuperuser


5개의 글을 추가해 보았다.



3.Using Django Rest Framework 구성하기

#django-rest-framework 설치
(conPython37) F:\project\PYTHON\deact>pip install djangorestframework



#(conPython37) F:\project\PYTHON\deact/deactBackend/settings.py>
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

'post',
'rest_framework', #추가
]

# 이하 추가
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
]
}


DRF(Django Rest Framework)는 자동으로 pk값을 index로 지정해서 뿌려준다.

Django 루트를 통해서 데이터를 JASON(JavaScript Object Notation)으로  주고 받을 수 있개 app의 views.py 를 통해서 JSON을 직렬화를 시켜주는 serializers.py를 작성하는데 DRF의  serializers 모듈이 사용 된다.



#(conPython37) F:\project\PYTHON\deact/post/serializers.py>
from rest_framework import serializers
from .models import Post

class PostSerializer(serializers.ModelSerializer):
class Meta:
fields = (
'id',
'title',
'contents',
)
model = Post


serializers.py 가 작성되었으면 views.py 에 등록하자


#(conPython37) F:\project\PYTHON\deact/post/views.py>
from django.shortcuts import render
from rest_framework import generics

from .models import Post
from .serializers import PostSerializer

# Create your views here.

class ListPost(generics.ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer

class DatailPost(generics.RetrieveUpdateDestroyAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer


django 루트에서 request가 올 경우 response를 해주기 위해 urls.py흫 Post 앱에 생성해주자


#(conPython37) F:\project\PYTHON\deact/post/urls.py>
from django.urls import path

from . import views

urlpatterns = [
path('', views.ListPost.as_view()),
path('<int:pk>/', views.DatailPost.as_view()),
]


Post 앱의 urls를 정의 하였으니 루트 의 urls를 정의할 차례이다


#(conPython37) F:\project\PYTHON\deact/deactBackend/urls.py>
from django.contrib import admin
from django.urls import path, include


urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('post.urls')),
]


(conPython37) F:\project\PYTHON\deact>python manage.py runserver


localhost:8000/api 로 접속해 보자.


 여기까지 왔으면 이제 django api서버의 준비는 완료된 것이다. 그리고 마지막으로 script태그 안에서의 api를 통한 데이터의 접근제어를 위해 HTTP 접근제어 규약(CORS : Cross-Origin Resource Sharing)을 추가해야한다. 간단하게 설명하자면 기존의 HTTP요청에서는 img나 link태그 등으로 다른 호스트의 css나 이미지파일 등의 리소스를 가져오는 것이 가능한데 script태그로 쌓여진 코드에서의 다른 도메인에 대한 요청은 Same-origin policy에 대한 규약으로 인해 접근이 불가하다. 하지만 아다시피 react는 거의가 script요청에 의해 페이지를 그리는 방식이므로 이제 대한 제약 해제가 필요하다. django로 돌아가고 있는 api서버와 페이지를 그려주는 react서버는 명목상 아예 다른 서버로 구분되기 때문이다.

출처 : 간단한-react-JS-Django-어플리케이션-만들기

위의 내용읠 적용 시키기위해 새로운 middleware package를 설치하고 아래와 같은 경로의 파일을 수정해보자


(conPython37) F:\project\PYTHON\deact>pip install django-cors-headers



#(conPython37) F:\project\PYTHON\deact/deactBackend/settings.py>
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

'post',
'rest_framework',
'corsheaders', #추가
]

REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
]
}

MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', #추가
'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_ORIGIN_WHITELIST = [
'http://localhost:3000',
'http://localhost:8000',
]



4.React 앱 작성하기




#(conPython37) F:\project\PYTHON\deact/src/App.js>
import React, { Component } from 'react';

class App extends Component {
state = {
posts: []
};

async componentDidMount() {
try{
const res = await fetch('http://127.0.0.1:8000/api/');
const posts = await res.json();
this.setState({
posts
});
} catch (e) {
console.log(e);
}
}

render() {
return (
<div>
{this.state.posts.map(item=> (
<div key={item.id}>
<h1>{item.title}</h1>
<span>{item.contents}</span>
</div>
))}
</div>
);
}
}


export default App;



(conPython37) F:\project\PYTHON\deact>python manage.py runserver


F:\project\PYTHON\deact>yarn start


djanog server 실행모습



React server 실행모습


MariaDB database 모습



프로젝트 트리구조나 자세한 source code를 보고 싶다면 

https://github.com/khjoony/deact 로 이동해 봅시다







댓글