0517 Client + Server 둘다 개발하기
cors 개념 익히기
cors 무엇일까?
우리 현재 배운느건클라이언트 구조
개발자는 프론트 백엔드 라고 생각한다
사용자가 보는 화면은 뷰 장고로 api 서버를 만드는 것을 백엔드 또는 서버라 부른다.
장고로는 API (백)를 사용하고 클라이언트를 자유롭게 사용하면 휴대폰, 데스크탑 등의 응용프로그램으로 만들수있다. ( 화면만 다른 언어로 만든다는 것 )
문제 Client + Server
Same Origin Policy (SOP)
브라우저 같은 출저에서 온 정보만 사용 가능!
다른 포트 == 다른 출저
CORS( Cross Origin Resource Sharing)
브라우저가 같은 출저가아니라도 가능
API Server 에서 white list 를 만든다고 생각하면 좋다.
다른 포트라도 가능하게끔 해주는 것이다.
TODO-SERVER
- 가상화 셋팅 후 가상환경에서 실행하자
- source venv/Scripts/activate
python -m venv venv && activate
- 필요 한 것들 설치
pip install django django-rest-framework django-seed
- 중간중간에 항상 리퀘스트 먼트해놓기!
pip freeze > requirements.txt
- 현재까지 디렉토리 내역
todo-app/
todo-client/
.....
todo-server/
venv/
- 장고 프로젝트만들기
django-admin startproject config .
- 바로 앱만들기
python manage.py startapp todos
settings.py
installd_apps
- todos와 rest_framework, django_seed 추가하기
INSTALLED_APPS = [
# Custom App
'todos',
# Third-party packages
'rest_framework',
'django_seed'
#Django core packages
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
models.py(모델링 하러가기)
- todos 폴더의 models.py
from django.db import models
# Create your models here.
class Todo(models.Model):
content = models.TextField()
completed = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
- 마이그레이션
python manage.py makemigrations
python manage.py migrate
Seed 집어넣기
python manage.py seed todos --number=5
config - urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/todos/', include('todos.urls')),
]
todos- urls.py
from django.urls import path
from . import views
urlpatterns = [
# todo list
# GET http://localhost:8000/api/v1/todos
path('', views.todo_list),
]
- views.py 로 패쓰해주자
from django.shortcuts import render
from rest_framework.decorators import api_view
# Create your views here.
@api_view()
def todo_list(request):
# 1. 모든 todo list 를 가져온다.
# 2. serilaize
# 3. 응답
pass
serializers.py
from rest_framework import serializers
from .models import Todo
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = (
'id', 'content', 'completed',
'created_at', 'updated_at',
)
views.py
- serializer 를 가져와준다.
from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .serializers import TodoSerializer
from . models import Todo
# Create your views here.
@api_view()
def todo_list(request):
# 1. 모든 todo list 를 가져온다.
todos= Todo.objects.all()
# 2. serilaize
serializer = TodoSerializer(todos, many=True)
# 3. 응답
return Response(data=serializer.data)
- 이제 요청을 보내보자
GET http://localhost:8000/api/v1/todos
todo-Client
- ls로 반드시 확인하기 ( 내폴더 맛는지)
- 후에 axios 설치
npm install axios
- vue 서버 키기
npm run serve
- localhost:8080에 들어가보자 ( vue)
- 8080 에서 django(8000) 으로 요청을 보내보자
- todo-client에 app.vue 로가보자
- computed 밑에다가 created 함수 만들어주기
- axios import 해주자
<template>
<div id="app" class="container">
<TodoForm/>
<div
v-if="errorMsg"
class="alert alert-danger my-2"
role="alert"
>
{{ errorMsg }}
</div>
<TodoList/>
</div>
</template>
<script>
import TodoForm from '@/components/TodoForm'
import TodoList from '@/components/TodoList'
import axios from 'axios'
export default {
name: 'App',
components: {
TodoForm,
TodoList,
},
computed: {
errorMsg() {
return this.$store.state.errorMsg
},
},
created() {
// 요청 주소 만들기
const TODO_LIST_URL = 'http://localhost:8000/api/v1/todos/'
axios
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
max-width: 600px
}
</style>
console.log 로 찍어보면 에러메세지가발생한다.
<template> <div id="app" class="container"> <TodoForm/> <div v-if="errorMsg" class="alert alert-danger my-2" role="alert" > {{ errorMsg }} </div> <TodoList/> </div> </template> <script> import TodoForm from '@/components/TodoForm' import TodoList from '@/components/TodoList' import axios from 'axios' export default { name: 'App', components: { TodoForm, TodoList, }, computed: { errorMsg() { return this.$store.state.errorMsg }, }, created() { // 요청 주소 만들기 const TODO_LIST_URL = 'http://localhost:8000/api/v1/todos/' axios.get(TODO_LIST_URL) .then((res) => { console.log(res) }) .catch((err)=>{ console.error(err) }) }, } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; max-width: 600px } </style>
- Access-Control-Allow-Origin 에러가뜬다
에러 해결하기
구굴에 django cors headers 라고 검색해준다.
(https://github.com/adamchainz/django-cors-headers)
- 설치방법 ( server 에서)
python -m pip install django-cors-headers
installed_apps( settings.py )에서 추가시켜주자
'corsheaders',
INSTALLED_APPS = [
# Custom App
'todos',
# Third-party packages
'rest_framework',
'django_seed',
'corsheaders',
#Django core packages
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE 에도 추가해주자
'corsheaders.middleware.CorsMiddleware',
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',
]
- 미들웨어 왜하나: 요청이오면 req 와 res 사이에서 처리해주는 곳
맨 아래에
CORS_ALLOWED_ORIGINS
를 기재해주자.모든 사이트에 허용해준다는 뜻
CORS_ALLOWED_ORIGINS = Ture
2차시
todo-client
- npm
npm install vue-router
main.js 로가보자
- view에서 settings.py 같은 역활을 하는 곳이다.
- router을 임포트 시켜주자
import Vue from 'vue'
import App from './App.vue'
import store from './store'
import UUID from 'vue-uuid'
import router from './router'
Vue.use(UUID)// 등록
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
- src 안에 router 폴더를 만들어준다. index.js 를 만들어주고 작성
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/todos',
name: 'todoList',
component: TodoView,
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
pages 라는 폴더를 생성하고 TodoView.vue 를 만들어준다.
<template> <div> <h1>Todo App</h1> </div> </template> <script> export default { name: 'TodoView', } </script> <style> </style>
- 그리고 router 폴더의 index.js 에 TodoView를 import 시켜줘야한다.
import TodoView from '@/pages/TodoView'
|component: TodoView,
import Vue from 'vue'
import VueRouter from 'vue-router'
import TodoView from '@/pages/TodoView'
Vue.use(VueRouter)
const routes = [
{
path: '/todos',
name: 'todoList',
component: TodoView,
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
npm run serve
를 통해서 서버가 켜지는지? 정상적으로 작동하는지 점검한다.app.vue 에서 아래 코드를 잘라내어준다
<TodoForm/> <div v-if="errorMsg" class="alert alert-danger my-2" role="alert" > {{ errorMsg }} </div> <TodoList/>
- 위 코드를 TodoView.vue 에 넣어준다.
app.vue 에서 또 아래코드를 잘래내준다
import TodoForm from '@/components/TodoForm' import TodoList from '@/components/TodoList'
TodoView.vue 에 넣어준다.
아래코드 app.vue 에서 잘라내준다.
components: { TodoForm, TodoList, },
- TodoView.vue 에 넣어준다.
App.vue
<template>
<div id="app" class="container">
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'App',
computed: {
errorMsg() {
return this.$store.state.errorMsg
},
},
created() {
// 요청 주소 만들기
const TODO_LIST_URL = 'http://localhost:8000/api/v1/todos/'
axios.get(TODO_LIST_URL)
.then((res) => {
console.log(res)
})
.catch((err)=>{
console.error(err)
})
},
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
max-width: 600px
}
</style>
TodoView.vue
<template>
<div>
<h1>Todo App</h1>
<TodoForm/>
<TodoList/>
</div>
</template>
<script>
import TodoForm from '@/components/TodoForm'
import TodoList from '@/components/TodoList'
export default {
name: 'TodoView',
components: {
TodoForm,
TodoList,
},
}
</script>
<style>
</style>
Tip - 네트워크에러가 개발자도구에서 콘솔로그로 뜰껀데 장고서버가 안켜져있어서 그렇다.
App.vue 에다가 특정 링크에 접속했을때 보여주는 화면은
<router-view/>
를 써줬다. 적어준다.그리고 아래 코드도 추가해주자.
<nav> <router-link>Todo</router-link> </nav>
- router link 에는 :to=""를 안적어줘도 된다 적는 것은 아래 데이터 값을 쓴다는 것이다.
App.vue
<template>
<div id="app" class="container">
<nav>
<router-link to="/todos">Todo</router-link>
</nav>
<router-view/>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'App',
computed: {
errorMsg() {
return this.$store.state.errorMsg
},
},
created() {
// 요청 주소 만들기
const TODO_LIST_URL = 'http://localhost:8000/api/v1/todos/'
axios.get(TODO_LIST_URL)
.then((res) => {
console.log(res)
})
.catch((err)=>{
console.error(err)
})
},
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
max-width: 600px
}
</style>
'SSAFY > Python문법 정리' 카테고리의 다른 글
[JS]Vue router (0) | 2021.05.10 |
---|---|
[JS] 새로고침 없이 좋아요, Follow 하기 (0) | 2021.05.06 |
[Python] Prim 알고리즘 (0) | 2021.04.21 |
[Python] 큐의 구조 (0) | 2021.03.03 |
[Python] 스택 2 (0) | 2021.02.24 |