SSAFY/Python문법 정리

[Vue + Django] Client+ Server

황성안 2021. 5. 17. 08:55
728x90

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>

 

728x90

'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