🐰 토끼반 알고리즘
🥕 자릿수 더하기 - 멋있는 답들 공부해보기
def sum_digit(number):
if number < 10:
return number;
return (number % 10) + sum_digit(number // 10)
def sum_digit(number):
return sum([int(i) for i in str(number)])
이거 진짜 내 머릿속을 딱 그대로 그려놓은건데 세상에 멋있는 사람 참많다.. 멋져..
💣 어제 타임어택 다시 훑어보기
✔️ 전처리(?) ⭐⭐⭐
- 깃헙 리포 만들어서 연결하기
- 깃이그노어 만들기
- 가상환경 만들기
- 가상환경에 패키지 설치하기
- 패키지 프리즈하기
- 패키지에 맞게 settings.py 설정해주기
- 커밋, 푸쉬해서 시작 커밋 남기기
✔️ serializer 내부 메소드 create, update
- serializer.save()시 실행됨
- create : 해당 시리얼라이저를 사용해서 생성(post)작업(객체 인스턴스가 없을 때)을 할 때 실행됨
- update : 해당 시리얼라이저를 사용해서 수정(put)작업(객체 인스턴스가 있을 때)을 할 때 실행됨
➜ 하나의 시리얼라이저로 여러가지 작업을 할 수 있게 됨
이외에도 validate()가 정의될 수 있음
✔️ views에서 사용되는 serializer.is_valid()
- validate는 serializer.is_valid()가 호출이 되면 실행이되는 메서드
- is_valid()로 유효성 검사를 마친 결과값이 serializer에 validated_data라는 인자로 들어감
📃 javascript
📍DOM(Document Object Model)
- HTML 문서에대한 인터페이스
- 뷰포트에 렌더링할 것을 정하고
- 페이지의 컨텐츠, 구조, 스타일이 JS에 의해 수정될 수 있다
📍Document.querySelector()
const example = document.querySelector('img')
const example = document.querySelector('img[src='']')
const example = document.querySelector('.img')
const example = document.querySelector('#img')
📍새로운 요소 만들기
- document.querySelector() html문서의 특정 부분을 선택하고
- document.createElement() 새로운 태그요소를 생성
- setAttribute()로 태그의 속성 생성(class, style..)
document.querySelector("#loginForm").setAttribute("style", "display:none");
- textContent()로 텍스트를 입력
- append/appendChild() 등을 이용해 처음 선택했던 부분(1)에 생성된 요소(2-4)를 붙인다
ex)
<section>
<h1>안녕</h1>
<h3>안녕안녕안녕</h3>
const section = document.querySelector('section');
const h2 = document.createElement('h2');
h2.setAttribute('class','title');
h2.textcontent ='안녕안녕';
section.appendChild(h2);
section.insertBefore(h2,h3);
📍localStorage 접근하기
- setItem() key, value 추가
localStorage.setItem("sparta_access_token", accessToken);
- getItem() value 읽어오기
document.querySelector("#refresh-token").value = localStorage.getItem("sparta_refresh_token");
- JSON.stringify() 제이슨 문자열로 변환
로컬스토리지에는 문자열만 저장되기때문에 객체나 배열을 저장하기위해서 변환
document.querySelector("#payload").value = JSON.stringify(localStorage.getItem("payload"));
🐋 DOCKER 2주차 3~4
🦀 docker로 컨테이너 생성 그 이후
- 항상 실습 시작은 인스턴스에 ssh 연결부터 !
ssh -i C:\Users\hyojine\Documents\mykeypair.pem ubuntu@54.180.106.117
- docker 명령어는 기본적으로 관리자 권한으로 실행되므로 꼭 sudo를 붙일 것
- sudo docker ps (-a): 실행중인 컨테이너 목록 확인(중지된 것까지 모두)
- sudo docker images : 컨테이너 생성시 사용되는 이미지 목록 확인
- sudo docker exec -it f730ee16b032 /bin/bash : 컨테이너 내부로 들어가보기 (/bin/bash 쉘이 없을 경우 /bin/sh)
- httpd 이미지 : 컨테이너 생성시 htdocs안에 있는 index.html을 사용자에게 보여줌
- exit : 컨테이너 중지하면서 나오기
🦀 docker-compose
- sudo mkdir -p /usr/lib/docker/cli-plugins : cli-plugins라는 디렉토리를 만드는데 -p 옵션으로 usr/lib/docker 경로가 없을시 자동으로 생성
- sudo curl -SL https://github.com/docker/compose/releases/download/v2.11.2/docker-compose-linux-x86_64 -o /usr/lib/docker/cli-plugins/docker-compose : 명령어 curl로 깃헙주소에 있는 도커파일을 방금 생성한 그 경로의 docker-compose 이름으로 다운받음
- ls -l /usr/lib/docker/cli-plugins/ : 경로에 docker-compose 잘 설치됐는지 확인
- sudo chmod +x /usr/lib/docker/cli-plugins/docker-compose : 리눅스에는 기본적으로 파일에대한 실행 권한이 없어서 권한(+x) 부여
- sudo docker compose version : 잘 설치됐는지 확인
- docker compose 명령어는 docker-cmpose.yml 파일이 존재하는 경로에서 실행할 것
🔖 북마크해둔 페이지들 정리
✔️ django MVT 패턴
- 웹 클라이언트 요청 ➜ urls ➜ views ➜ (models ➜ DB) ➜ Templates
- URLconf : urls - views 매핑
- HTTPRequest : Header(&Body)
- Path Converter : <type:name>
- url을 정교하게 하자면 path 대신 re_path & 정규표현식 사용
- view함수는 첫번째 인자로 HTTPRequest를 받음(=request)
- template은 장고 템플릿 시스템 사용
- template 경로는 settings.py의 TEMPLATE_DIRS
✔️ QuerySet
-
전달받은 모델의 객체 목록
-
Model.objects.all() : 모든 객체목록 조회
➜ <QuerySet [<Post: my post title>, <Post: another post title>]>
이런 형태로 나옴
-
Model.objects.filter(조건)
ex) Post.objects.filter(title__contains='title') title에 'title'이 들어간 글자만 뽑아내겠다
✔️ JSON.parse()
- string 객체를 json 형태로 변환시켜줌
✔️ .env(dotenv) 사용법
- 노출되어선 안되는 정보들이 깃에 올라가지 않도록 이런 정보들을 환경변수로 사용
- .gitignore 에 .env있는지 확인하기
python -m pip install django-environ
- .env 파일 만들기 (venv, manage.py, requirements.txt 등과 같은 경로에)
- .env 파일 안에 중요한 정보들 작성
- settings.py 에서 설정
from environ import Env
env = Env()
env_path = BASE_DIR / ".env"
if env_path.exists():
with env_path.open("rt", encoding="utf8") as f:
env.read_env(f, overwrite=True)
✔️ 프로젝트 이슈 유형
이번에 코드리뷰하면서 보니까 이슈 유형이 있는데 뭐가 뭔지 알 수 없어서 정리해본다
Theme > Initiative | Epic > Story = Task = Bug > Subtask
- Theme : 조직의 목표
- Initiative : Theme 달성을 위한 목표, 여러 epic으로 이뤄져있음
- Epic : 큰 규모의 업무 및 목표, 여기서부터 이슈로 간주
- Story : Epic 달성을 위해 수행할 업무를 클라이언트 입장에서 작성
- Task : Epic 달성을 위해 수행할 기술적 업무
- Bug : Epic 달성을 위해 수행하면서 발생한 버그 추적
- Subtask : Task를 쪼갤 때 사용
✔️ jwt 인증
- 인증정보가 서버에 저장되지 않아서 stateless 라고 표현함
- 인증 정보를 (클라이언트에서) 서버로 전달(로그인/회원가입)해서
- 서버에서 인증 처리
- jwt를 생성해서 클라이언트로 다시 전달
- 브라우저에 jwt 저장(localStorage)
- 이후 인증요청엔 모두 jwt이용
- 서버가 jwt 검증해서 인증 처리
- 만료되면 refresh
JSON.stringify() 제이슨 문자열로 변환
로컬스토리지에는 문자열만 저장되기때문에 객체나 배열을 저장하기위해서 변환
document.querySelector("#payload").value = JSON.stringify(localStorage.getItem("payload"));
왜 PARSE가 아니고 STRINGIFY를 해주지??? 로컬스토리지엔 스트링이 저장된다면서??