
기간
2024.06.03 ~ 2024.06.07
한 주를 마치며
어느 덧 캠프에 참여한지 5주가 지났다.
이번 한 주 동안 새로 오신 강사님의 수업 방식에 완전히 적응해가고 익숙해지기까지 오랜 시간이 걸리지 않았다.
내가 느낀 강사님은 애자일(Agile) 개발 프로세스를 강조하시고 중요하게 생각하시는 분이신 것 같았다.
전에 다니던 회사에서도 애자일 개발 방법을 도입하였지만, 실제로 개발하면서 제대로 된 애자일 방법으로 진행되는 것 같진 않은 느낌이었다. "왜 회사에서 잘 되지 않았을까?" 라고 다시 생각해보면 개발자들 뿐만 아니라 PM, 디자이너, 기획자 등 프로젝트에 참여한 모든 인원이 애자일 방법에 대해 잘 이해하고 사용할 줄 알아야 하지 않았을까? 라는 생각이 들게 되었다.
아무튼, 새로 오신 강사님은 애자일 개발 방법을 오랜 시간동안 사용하신 분 같아 보였고, 이 참에 제대로 배워볼 생각이다.
수업은 보통 오전에는 지난 날 내주신 과제에 대한 코드 리뷰를 하는 시간이 되었고, 오후에는 수업 진도를 나가는 시간이 되었다.
코드 리뷰는 강사님이 과제를 제출한 학생들의 코드를 보고 어떤 부분이 미미했고, 어떤 부분이 잘했는지, 어떻게 고쳐야 되는지 리뷰를 해주는 시간이었고, 코드 리뷰 시간동안 내가 느낀 점은 대부분의 과제를 제출한 학생들은 거의 비슷한 부분에서 실수(?)를 한다는 것이었다.
오후에는 Vue에 대해 수업을 하셨고, 맨 처음 강사님께서 React와 Vue를 고민하시다가 Vue를 선택하시게 되었는데, 이 때 내심 매우 아쉬었다. React를 했으면 ... 좋았을텐데 ... ㅋㅋㅋ
그래도 내 주위 지인말로는 React를 알고 있는 상태에서 Vue를 사용하기까지 일주일이면 충분할만큼 React보다는 쉽다고 말해주셔서, 내심 안심이 되긴했다. 그리고, 수업시간동안 Vue를 써보면서 실제로 React랑 큰 차이를 느낀 점이라면, 엄청 코드가 간단하다는 것이다.
추가적으로, 이번 한 주동안 바보같이 에어컨을 18도로 해놓고 자버려서 감기로 고통받는 한 주 였다... 😷😷😷
수업 내용
Vue
Django
DDD(IoC와 결합한?)
What I Learned In A Week
Vue와 Django 통신 연결 하는 방법
""" | |
Django settings for manual_proj project. | |
Generated by 'django-admin startproject' using Django 5.0.6. | |
For more information on this file, see | |
https://docs.djangoproject.com/en/5.0/topics/settings/ | |
For the full list of settings and their values, see | |
https://docs.djangoproject.com/en/5.0/ref/settings/ | |
""" | |
from pathlib import Path | |
# Build paths inside the project like this: BASE_DIR / 'subdir'. | |
BASE_DIR = Path(__file__).resolve().parent.parent | |
# Quick-start development settings - unsuitable for production | |
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/ | |
# SECURITY WARNING: keep the secret key used in production secret! | |
SECRET_KEY = "Hoony's Secret Key" | |
# SECURITY WARNING: don't run with debug turned on in production! | |
DEBUG = True | |
ALLOWED_HOSTS = [] | |
# Application definition | |
INSTALLED_APPS = [ | |
"corsheaders", | |
"django.contrib.admin", | |
"django.contrib.auth", | |
"django.contrib.contenttypes", | |
"django.contrib.sessions", | |
"django.contrib.messages", | |
"django.contrib.staticfiles", | |
"rest_framework", | |
"board", | |
] | |
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", | |
] | |
# pip3 install python-dotenv | |
# pip3 install django-cors-headers | |
import os | |
from dotenv import load_dotenv | |
load_dotenv() | |
ROOT_URLCONF = "manual_proj.urls" | |
CORS_ALLOWED_ORIGINS = os.getenv("CORS_ALLOWED_ORIGINS", "").split(",") | |
CSRF_TRUSTED_ORIGINS = os.getenv("CSRF_TRUSTED_ORIGINS", "").split(",") | |
CORS_ALLOWED_ORIGINS = ["http://localhost:8080", "http://127.0.0.1:8080"] | |
TEMPLATES = [ | |
{ | |
"BACKEND": "django.template.backends.django.DjangoTemplates", | |
"DIRS": [], | |
"APP_DIRS": True, | |
"OPTIONS": { | |
"context_processors": [ | |
"django.template.context_processors.debug", | |
"django.template.context_processors.request", | |
"django.contrib.auth.context_processors.auth", | |
"django.contrib.messages.context_processors.messages", | |
], | |
}, | |
}, | |
] | |
WSGI_APPLICATION = "manual_proj.wsgi.application" | |
# Database | |
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases | |
DATABASES = { | |
"default": { | |
"ENGINE": "django.db.backends.sqlite3", | |
"NAME": BASE_DIR / "db.sqlite3", | |
} | |
} | |
# Password validation | |
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators | |
AUTH_PASSWORD_VALIDATORS = [ | |
{ | |
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", | |
}, | |
{ | |
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", | |
}, | |
{ | |
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", | |
}, | |
{ | |
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", | |
}, | |
] | |
# Internationalization | |
# https://docs.djangoproject.com/en/5.0/topics/i18n/ | |
LANGUAGE_CODE = "en-us" | |
TIME_ZONE = "UTC" | |
USE_I18N = True | |
USE_TZ = True | |
# Static files (CSS, JavaScript, Images) | |
# https://docs.djangoproject.com/en/5.0/howto/static-files/ | |
STATIC_URL = "static/" | |
# Default primary key field type | |
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field | |
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" |
우선 django의 settings.py에서 중요하다고 느낀 부분이 아래의 코드부분이다.
import os | |
from dotenv import load_dotenv | |
load_dotenv() | |
ROOT_URLCONF = "manual_proj.urls" | |
CORS_ALLOWED_ORIGINS = os.getenv("CORS_ALLOWED_ORIGINS", "").split(",") | |
CSRF_TRUSTED_ORIGINS = os.getenv("CSRF_TRUSTED_ORIGINS", "").split(",") |
우선 위 코드 작업을 하려면 python-dotenv와 django-cors-headers 라이브러리를 설치해야 한다.
CORS_ALLOWED_ORIGINS는 응답 헤더로부터 허용할 원본 목록을 의미하고,
CSRF_TRUSTED_ORIGINS는 안전하지 않은 요청을 위한 신뢰할 수 있는 원본 목록을 의미한다.
위 코드에서는 os.getenv로 .env로 부터 CORS_ALLOWED_ORIGINS와 CSRF_TURSTED_ORIGINS를 가져와서 설정해 주었다.
const actions: BoardActions = { | |
async requestBoardListToDjango( | |
context: ActionContext<BoardState, any> | |
): Promise<void> { | |
try { | |
const res: AxiosResponse<any, any> = | |
await axiosInst.djangoAxiosInst.get("/board/list"); | |
const data: Board[] = res.data; | |
context.commit(REQUEST_BOARD_LIST_TO_DJANGO, data); | |
} catch (error) { | |
console.error("requestBoardListToDjango(): " + error); | |
throw error; | |
} | |
}, | |
}; |
위는 vue의 actions.ts의 코드 부분이고,
Vue의 상태 관리 라이브러리인 Vuex와 Axios를 사용하여 Django 서버에서 게시판 목록을 가져오는 비동기 작업을 정의하고 있는 부분이다.
const res: AxiosResponse<any, any> = await axiosInst.djangoAxiosInst.get("/board/list"); |
axios를 사용하여 Django 서버의 /board/list 엔드포인트로 GET 요청을 보내고 Axios의 응답 객체인 res 변수에 담는다.
const data: Board[] = res.data; |
서버로부터 받은 응답 데이터를 data 변수에 할당하고, 이 데이터는 Board 타입의 배열의 형태이다.
context.commit(REQUEST_BOARD_LIST_TO_DJANGO, data); |
context.commit 메서드를 호출하여 Vuex의 변이(mutation)를 트리거한다.
Django와 Vue에서 이러한 작업을 하는 이유는 Cors 에러를 해결하기 위함이고,
Django와 Vue의 세팅이 정상적으로 완료된 후 Django의 서버를 실행시키고, /board/list에 접속하게 되면 아래 사진과 같이 정상적으로 200이 떨어지는 것을 볼 수 있다.
HTTP 상태 코드에 대한 설명은 내가 적어둔 아래 링크에서 더 정확히 확인할 수 있다.
https://hoonni3002.tistory.com/112
HTTP Status Code
HTTP Status Code상태 코드는 3자리 숫자로 만들어져 있으며, 첫번째 자리는 1에서 5까지 제공된다.첫번째 자리가 4와 5인 경우는 정상적인 상황이 아니기 때문에 사이트 관리자가 즉시 알아야 하는
hoonni3002.tistory.com

Django의 서버가 정상적으로 구동되는 것을 확인하고, Vue를 구동하게 되면 아래와 같이 정상적으로 작동하는 것을 확인 할 수 있다.

맨 처음에 Vue를 구동하고 아래와 같이 runtime errors 화면이 보게 되었는데, 노트북에서 실행하게 되면 아래와 같이 runtime errors를 자주 볼 수도 있다.

이 오류를 해결하는데 오랜 시간이 걸렸는데, 해결하고 난 뒤 엄청 어이없게 해결이 되었다..
이를 해결하는 방법은 캐시 비우기 및 강력 새로고침을 하면 된다..
왜인지는 모르겠지만, 노트북에서는 데스크탑과 달리 캐시를 저장하는 방식이 조금 다른 것 같아서, 노트북을 사용하여 vue를 구동시키면 위와 같은 화면을 볼 수도 있다.
전에 React로 개발하면서 위와 같은 오류를 많이 자주 봤었고, 똑같은 방법으로 해결하였는데, 오랜만에 위의 오류를 마주하니 바로 떠오르지않고, 해결하지 못한 나였다 ..
6주차 계획
🔥 복습만이 살길이다 ..!!!!
🤨 블로깅 많이하기 !!!!! (처음에 비해 블로깅을 안하고 있는 나 ... 초심으로 돌아가자 !)
🤝 아직도 같은 팀원들말고는 친해진 분이 없다 ...😪 더 .. 노력해보자 ..
👏 화이팅하기 !!
'SKN Family AI Camp > Memoir' 카테고리의 다른 글
SK Networks Family AI Camp 8th 회고록(24.06.24-24.06.28) (7) | 2024.06.30 |
---|---|
SK Networks Family AI Camp 2nd 회고록(24.05.13-24.05.17) (0) | 2024.05.20 |
SK Networks Family AI Camp 1st 회고록(24.05.08-24.05.10) (1) | 2024.05.13 |