오늘 배운 것

오늘은 삽질해서 막히던 SZ-85번의 하위 이슈 중 하나를 팀원들의 도움으로 같이 해결했다. 세부 문제 상황은, 투두 리스트들 아래 텍스트 인풋을 받는 Input 컴포넌트를 누르면 텍스트 인풋 창이 활성화되지 않고 키보드가 활성화되었다가 바로 비활성화되는 문제였다. 

팀원들과 웹엑스로 회의를 하면서 문제가 되는 컴포넌트(DailyTodos 안의 컴포넌트)를 KeyboardAvoidingView로 한번 더 감싸 보았더니 된다고 했다. 

 

사실 어떤 원리로 문제가 해결되었는지는 모르겠다. 왜냐하면 이미 바깥 화면에서 KeyboardAvoidingView를 사용하고 있었고, 그래서 굳이 한번 더 감쌀 생각을 안 한 것이었기도 하기 때문이다. 또한 GPT한테 물어봤을 때는 컴포넌트(아마도 Input 컴포넌트)가 계속 텍스트창이 활성화될 때마다 다시 렌더링 되어서 텍스트 창 클릭 -> 활성화 -> 다시 렌더링됨 -> 초기 값인 비활성화...의 루프를 타는 것이라고 생각하였는데 결국 그도 아니었던 것이다. 

 

이 부분은 KeyboardAvoidingView에 대해서도 더 알아봐야 알 수 있을 것 같고, 그래도 모호하다면 멘토님께 이 상황을 한번 공유드려봐도 어떤 실마리가 보일 것 같다. 이제 다음 하위 이슈들을 처리할 수 있을 것 같아 마음이 조금이나마 홀가분해졌다. 

 

 

아직 SZ-85번 이슈의 완료를 위해선 몇 개의 하위 이슈들이 남아있지만, 이걸 완료해야 다른 팀원이 '드래그앤드롭 기능과 현재 컴포넌트를 연결하는 이슈' 및 'AI가 하위투두를 자동으로 생성해주는 이슈'를 처리할 수 있어서, 이걸 얼른 완료하는 게 중요하다. 그래야 나도 다음 급한 이슈인 'ECR, ECS를 통해 자동 배포하기'를 해볼 수 있을 것 같다. 암튼 파이팅이다.

 

'개발 일기장 > SWM Onestep' 카테고리의 다른 글

20240727 TIL: ECR ECS 적용기  (0) 2024.07.27
20240726 TIL  (0) 2024.07.26
20240724 TIL  (0) 2024.07.24
20240723 TIL  (2) 2024.07.23
20240721 TIL  (1) 2024.07.22

 오늘 배운 것

오늘도 SZ-85번 이슈에서 삽질을 했다. 대부분은 상태관리에 관한 문제였다. 특히 프로젝트에서는 상태관리를 위해 zustand와 useContext API를 사용하는데, zustand 라이브러리를 통해서는 useTodoStore()와 useModalStore()라는 2가지의 store를 사용한 것이 복잡성의 원인이 되었다. 

 

정확히는 selectedTodo라는 모달창에서 선택된 투두를 저장하기 위한 상태 변수가 useModalStore()에 선언되어 있었는데, 이것을 useTodoStore()에 선언된 줄 알고 useTodoStore에서 불러와서 제대로 모달창이 나타나지 않는 문제가 있었다. 

 

또한 Jwt Parse error도 있었다. GPT에게 물어보니 토큰이 발급된 시간(iat)가 컴퓨터의 로컬 시간보다 빨라서 발생하는 에러로, 컴퓨터의 로컬 시간을 점검해 볼 것을 말해줬다. 나는 맥을 쓰고 있어서, 맥의 환경설정에 들어가서 서버가 애플의 시간 서버(time.apple.com)에서 제대로 시간을 받아오고 있는지를 확인했다. 그런데 이미 애플의 서버에서 제대로 현지 시각을 잘 받아오고 있어서, 오류의 원인은 알았지만 해결은 할 수 없었다... 현재 오류는 확률적으로 발생하는데, 만약 매번 또는 빈번하게 발생한다면 그때 더 자세히 알아봐야 할 것 같다. 

 

'개발 일기장 > SWM Onestep' 카테고리의 다른 글

20240727 TIL: ECR ECS 적용기  (0) 2024.07.27
20240726 TIL  (0) 2024.07.26
20240725 TIL  (0) 2024.07.25
20240723 TIL  (2) 2024.07.23
20240721 TIL  (1) 2024.07.22

 오늘 배운 것

투두 안에 하위 투두가 있고, 각 투두의 설정 아이콘을 눌러 모달창을 열 수 있고, 그 모달창을 통해 투두를 수정 및 삭제할 수 있는 기능을 개발 중이다. 원래 어제부터 만들었었는데, 시간을 많이 썼음에도 문제가 하나 터지고 겨우 해결하면 또 다음 게 생기고 이런 식이라서 아직도 막히고 있다. 

 

오늘 배운 것은 상태 관리의 중요성이다. 투두 컴포넌트들은 크게 CategoryTodos > DailyTodos > DailyTodo > DailySubTodo의 계층 구조(사실 이 정도면 그냥 재귀 구조로 호출해도 될 것 같다...)로 되어 있는데, 문제는 TodoModal이라는 모달창 컴포넌트의 위치였다. 원래는 이 TodoModal이 DailyTodo와 DailySubTodo 컴포넌트에 있었는데, 그러다 보니 카테고리 값을 바꾸고 나서 투두를 클릭할 때 상태 관리가 제대로 되지 않아서 이전 카테고리의 투두 값을 모달에 띄운다는 문제가 있었다. 

 

요즘은 개발을 할 때 GPT와 티키타카를 많이 하는데, 내가 문제 상황을 인식해서 그걸 풀어서 설명하면 GPT가 해결책을 제시해주고, 그럼 내가 그걸 따라해보거나 찾아보면서 이해하는 식으로 작업하고 있다. 모든 투두 컴포넌트 파일들을 첨부하고 GPT에게 위의 문제를 해결할 방법을 제시해달라고 하니, GPT는 기존의 CategoryTodos > DailyTodos > DailyTodo > TodoModal의 구조 대신 TodoModal을 CategoryTodo의 바로 아래, DailyTodos와 같이 배치했다. 그리고 그 대신 useContext나 zustand를 사용해서 상태 관리를 하는 식으로 코드를 제시해줬다. 

 

그래서 이 방법을 사용해서 기존에 있었던 zustand로 투두 상태를 관리하는 useTodoStore() 대신, useModalStore()를 사용했다. 사실 상태 관리나 컴포넌트 작성에 정답은 없어서 useContext()를 사용할지 zustand를 사용할지 고민이었는데, 단순 변수와 set 함수(useState를 통해 쌍으로 생성되는 변수와 함수)만 있는 게 아니라면 zustand도 괜찮을 것 같다고 판단해서 zustand를 사용했다. 

 

아직 모달창은 시작도 못 했고, CategoryTodos 컴포넌트 안에서도 해결해야 할 과제가 많이 남아있어 막막하지만, 근데 또 시간을 많이 썼는데 안 된 거라서 조금만 더 해보고 안 되면 일단 자고 내일 일찍 일어나서 조금이라도 더 해 봐야 할 것 같다. 늘 항상 막힘없이 개발이 잘 되는 게 아니고 막힐 때가 더 많은데, 오늘은 그런 날이었던 것 같다. 그래도 그런 날의 기록이라도 남기길 잘한 것 같다:)

 

 

'개발 일기장 > SWM Onestep' 카테고리의 다른 글

20240727 TIL: ECR ECS 적용기  (0) 2024.07.27
20240726 TIL  (0) 2024.07.26
20240725 TIL  (0) 2024.07.25
20240724 TIL  (0) 2024.07.24
20240721 TIL  (1) 2024.07.22

오늘 배운 것

github actions, workflow를 이용해서 CI/CD를 구축할 때는 무작정 AWS EC2 서버에 접속해서 도커를 띄우는 것이 아니다. 

대신 AWS의 ECS(Elastic Container Service), ECR(Elastic Container Registry) 서비스를 사용한다. 즉 순서는 다음과 같다. 

1. github actions에서 도커 이미지를 만든 다음에 ECR에 올린다. 

2. ECR의 signal을 사용해서 ECS에게 ECR에 도커 이미지가 업로드되었다고 알림을 보내거나, github actions에서 직접 ECS에게 알림을 보낸다. 

3. 배포 완료

 

그리고 도메인을 처음으로 돈 주고 사 보았고, 그것을 Route53이라는 AWS의 서비스를 통해서 AWS와 연결시켜 보았다. 구체적인 스텝이 정확히는 기억이 안 나서 겨우겨우 약간이나마 복기해 보았다. 

1. 여러 사이트를 통해서 도메인 사기

2. Route53을 이용해서 도메인 연결하기

3. 서브넷 설정하기. 그래야 하나의 서버가 실행되다가 죽어도 다른 서브넷의 서버로 연결할 수 있다고 하셨던 것 같다. 

4. 로드 밸런서 설정하기. 각 지역(aws region)에 따라서 request가 들어오면 그에 맞는 region의 subnet으로 보내주는 역할이라고 이해했다. 

 

또한 우리가 있는 ap-northeast-2 aws region은 서브넷이 크게 4개(2a, 2b, 2c, 2d)이기 때문에, 총 서브넷은 기본으로 생성되어 있는 private 서브넷 4개와, 우리가 직접 생성한 public 서브넷 4개로 총 8개면 된다고 하셨다. 

 

그리고 CloudWatch로 로그도 저장해야 한다고 하셨다. 백엔드의 경우는 CloudWatch, 프론트의 경우는 잘 모르지만 알아보아야겠다. 

 

또한 배포용 DB라면 RDS를 사용하는 것이 제일 깔끔하다고 말씀해 주셨다. 

또한 LexoRank 라이브러리도, 원래는 프론트 단에서만 정렬을 하려고 했는데 그럴 수가 없다고 하셨다. 왜냐하면 프론트 단에서 정렬 관련 정보를 보내면 백엔드에서 이를 아예 validation하지 않고 저장하는 것은 거의 사실상 불가능하기 때문이다. 

 

더 궁금한 것

도커 대신 ECR, ECS를 사용하는 것이 권장되는 이유가 궁금하다. 

github workflow도 내부 소스코드를 보면 github actions를 통해 구현된 것이라고 한다. 이 원리가 궁금하다. 

 

'개발 일기장 > SWM Onestep' 카테고리의 다른 글

20240727 TIL: ECR ECS 적용기  (0) 2024.07.27
20240726 TIL  (0) 2024.07.26
20240725 TIL  (0) 2024.07.25
20240724 TIL  (0) 2024.07.24
20240723 TIL  (2) 2024.07.23

프로그램을 진행하면서 새 맥북을 받았다! 너무 기뻤지만, 항상 사용하던 윈도우 노트북에서 새 맥북으로 바꾸려니 초기 설정부터 다시 해야 한다는 문제점이 있었다. 

 

혹시라도 내가 다음에 또 노트북을 바꾸게 되거나, 비슷한 개발자들이 있다면 참고할 수 있도록 하기 위해서 간략하게나마 글을 적어본다. 

 

설치할 프로그램들

1. brew

이 사이트에서 homebrew를 설치할 수 있다. 나는 homebrew는 mac에서 사용하는 일종의 패키지라고 알고 있고, 실제로 앞으로 설치할 많은 프로그램들(git, docker 등)이 brew install ___으로 간단히 설치가 가능하므로, 맥 사용자라면 homebrew 설치는 거의 필수적이라고 볼 수 있다. 

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

 

2. git

brew install git

 

잘 설치되었는지 확인해준다. 

git --version

 

3. docker

brew install docker

 

잘 설치되었는지 확인해준다. 

docker --version

 

4. iterm

필수 사항은 아니지만, 맥에서 기본으로 제공하는 터미널이 예쁘지 않다는 의견이 많아서 내 주변 맥 사용자들도 다 iterm을 사용하는 것 같아서 깔아봤다. 공식 사이트에서 설치할 수 있다. 

 

5. python

지금 개발중인 프로젝트에서는 python, django를 사용하므로 파이썬도 깔아줬다. 공식 홈페이지에서 맞는 버전을 사용하면 된다. 

 

6. java

지금 개발에서 사용하는 언어는 아니지만, 앱 개발을 하려면 android studio가 필요하고 android studio에서는 java를 필요로 하기 때문에 결론적으로 java도 필요했다. 주의할 점은, java를 설치하는 방법이 꽤나 여러가지라는 것이다. 그리고 android studio에서 빌드를 실행시키다 보면 jdk와 gradle의 버전이 맞지 않아서 나는 오류가 있다. 

이 사이트에서는 여러 자바 버전을 설치할 수가 있어서 여러 블로그들을 찾아보다 이 사이트에서 특정 jdk 버전을 다운받아서 오류를 해결하였다. 

 

자바가 잘 설치되었는지 확인하는 명령어는 다음과 같은데, 당연하게도 처음에 이 명령어를 입력하면 java, javac를 인식하지 못한다. 

java -version
javac -version

 

그 이유는 java에 대해서 환경변수 등록을 해주지 않았기 때문이다. 

맥에서는 루트 폴더 기준으로 .zshrc 라는 파일에 여러 환경변수 경로를 설정할 수 있는데, 이 안에 다음과 같이 입력해 주자. 

 

참고로 맥에서 파일을 읽거나 쓰기 위해서는 vim 이나 nano 명령어를 사용한다. 그러니까 iterm의 초기 디렉토리에서 다음과 같이 입력하면 아마도 .zshrc 창이 열릴 거다. 

vim .zshrc

 

여기서 -v 다음에 있는 17의 경우, 나의 경우는 jdk 17을 사용하고 싶어서 제한을 둔 것이다. 만약 다른 버전의 jdk를 명시적으로 사용하고 싶다면 17 대신 다른 숫자를 입력하면 된다. 

export JAVA_HOME=$(/usr/libexec/java_home -v 17)
export PATH=$JAVA_HOME/bin:$PATH

 

아래와 같은 명령어로 .zshrc 파일에서 변경된 내용을 반영해 준 다음, 다시 자바의 버전을 확인해보면 될 것이다. 

source .zshrc

 

아 그리고 자바 버전이 여러 개 깔려있을 때에도 중요한 내용인데, android studio에서 사용하는 gradle에서 특정 jdk를 사용하도록 설정하고 싶을 수 있다. 

gradle과 관련된 설정 파일은 보통 iterm의 초기 디렉토리에서(iterm을 열면 맨 먼저 보이는 기본 경로) .gradle > gradle.properties 파일 안에 있다(없으면 그 파일을 만들면 된다). 

 

파일을 만들고 싶다면 touch 명령어를 사용해 보자. 

touch gradle.properties

 

이후 vim이나 nano로 해당 파일을 열어준 뒤, 다음과 같이 입력했다. 나의 경우는 다음과 같다. 

org.gradle.java.home=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home

 

org.gradle.java.home 이라는 속성의 값을 java가 위치한 경로로 설정하는 것이 중요하다. 만약 이 경로를 모르겠다면 다음과 같이 입력해서 java가 어디 설치되어 있는지 찾아볼 수 있다. 

which java

 

나의 경우 이렇게 입력하면

/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/bin/java

 

이렇게 나오는데, 이 중에서 뒤에 /bin/java를 뺀 값을 경로로 지정해 주면 된다. 

 

7. visual studio code

공식 사이트에서 설치할 수 있다. 

 

8. android studio

공식 사이트에서 설치할 수 있다. 

 

 

 

 

 

 

 

 

 

'server-side > server' 카테고리의 다른 글

웹 어플리케이션 서버(WAS)  (0) 2024.08.05
Software Release Life Cycle  (0) 2023.07.15
OAuth 2.0 기본원리  (0) 2022.09.26
인증(Authentication)  (0) 2022.07.14
linux: cron 사용해서 자동으로 스케줄 실행하기  (0) 2022.07.09

문제

https://school.programmers.co.kr/learn/courses/30/lessons/1844

 

풀이

그래프 형식의 문제이니만큼 그래프 탐색을 이용했고, BFS로 풀었습니다. 

 

우선 BFS에 필요한 큐를 구현하기 위해서 collections 라이브러리의 deque 자료구조를 사용했습니다.

 

일반 리스트로도 pop(0) 메소드를 통해 큐의 역할을 구현할 수는 있지만 이 경우 맨 앞의 원소를 제거할 때는 O(n) 시간이 걸린다는 단점이 있어서 deque() 라이브러리를 사용했습니다. 

 

from collections import deque

def solution(maps):
    
    m = len(maps)
    n = len(maps[0])
    dx = [-1, 1, 0, 0]
    dy = [0, 0, -1, 1]
    
    def bfs(start_x, start_y, end_x, end_y):
    	# 거리 정보를 저장하는 배열. 시작점에서 닿을 수 없는 경우 -1의 값을 가짐
        dist = [[-1] * n for _ in range(m)]
        Q = deque([(start_x, start_y)])
        dist[start_x][start_y] = 1
        
        while Q:
            cur_x, cur_y = Q.popleft()
            for k in range(4):
                nx = cur_x + dx[k]
                ny = cur_y + dy[k]
                
                # 배열 인덱스를 벗어나는 경우
                if nx < 0 or nx >= m or ny < 0 or ny >= n:
                    continue
                    
                # 벽인 경우
                elif maps[nx][ny] == 0:
                    continue
                    
                # 한 번도 방문하지 않은 경우만 큐에 추가
                # 최단거리로 방문하려면 같은 블럭을 두 번 이상 방문하는 일은 없어야 한다.
                if dist[nx][ny] == -1:
                    dist[nx][ny] = dist[cur_x][cur_y] + 1
                    Q.append((nx, ny))
                    
        return dist[end_x][end_y]
    
    return bfs(0, 0, m-1, n-1)

 

문제

https://school.programmers.co.kr/learn/courses/30/lessons/258705

 

참고한 가이드

카카오 기술 블로그에 나온 풀이 방법을 참고했습니다.

해당 블로그의 5번 문제에 풀이 과정이 잘 설명되어 있으니 궁금하신 분은 참고하시면 좋을 것 같습니다. 

https://tech.kakao.com/2023/12/27/2024-coding-test-winter-internship/

 

풀이

해당 풀이에서는 DP(dynamic programming) 방법을 설명해주셔서 배열을 선언한 뒤 각 인덱스에 점화식을 적용하는 방식으로 풀었습니다. 

 

def solution(n, tops):
    a = [0] * (n+1)
    b = [0] * (n+1)
    a[0] = 0
    b[0] = 1
    for i in range(1, len(a)):
        a[i] = (a[i-1] + b[i-1]) % 10007
        if tops[i-1] == 1:
            b[i] = (2 * a[i-1] + 3 * b[i-1]) % 10007
        else:
            b[i] = (a[i-1] + 2 * b[i-1]) % 10007
    answer = (a[n] + b[n]) % 10007
    return answer

 

⚠️

아래 공식문서를 읽고 인증 관련된 내용 중 일부만 발췌해서 정리했습니다.

자세한 내용이 궁금하시다면 공식문서를 참고하시는 것을 추천드립니다. 

https://docs.djangoproject.com/en/5.0/topics/auth/customizing/

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

✅custom user model 설정하기

 

settings.py 파일의 AUTH_USER_MODEL 변수의 값을 "app이름.Model이름" 으로 설정하자. 

AUTH_USER_MODEL = "account.CustomUser"

 

또한 공식문서에서는 인증 모델의 정보에 접근할 때는 쿼리셋을 작성할 때 흔히 사용하는 방식(CustomUser.objects....) 보다는 django.contrib.auth 모듈의 get_user_model() 사용을 권장한다. 

 

이유는 다른 auth user model을 사용하는 다른 프로젝트에서 코드를 사용할 때 충돌이 날 수 있어서라고 한다. 

 

확장성 있는 코드를 작성하고 싶다면 공식문서대로 하는 것이 좋겠고, 다른 프로젝트에서 코드를 사용할 일이 없다면 크게 상관없지 않을까 싶다. 

 

✅인증 정보 구분하기: profile model, proxy model

공식 문서에서는 인증 관련 정보는 user 모델에, 유저와 관련된 그 외 다른 정보는 다른 모델(profile model)에 저장하는 것을 권장한다. 

 

예를 들어 profile model이 Employee라고 하면, Employee와 User 모델의 관계를 1:1 또는 외래키로 설정하는 것이다. 

class Employee(models.Model):
	user = models.OneToOneField(User)
	...

 

반면 인증 관련 정보 외에 추가로 정보를 저장할 필요는 없지만 User 모델이 동작하는 방식을 바꾸고 싶다면 proxy model을 사용하는 것도 좋다. 

 

프록시 모델(proxy model)을 사용하면 유저 모델에서 사용 가능한 메소드나 쿼리셋의 정렬 등을 유저 모델과 다르게 설정할 수 있다. 

class Member(CustomUser):

	class Meta:
		proxy = True

 

✅User model Customizing

공식문서에서는 유저 모델을 정의할 때 django.contrib.auth.models 모듈의 AbstractBaseUser를 상속해서 사용하는 것을 권장한다. 

 

AbstractUser는 장고의 기본 유저 모델인 만큼 인증에서 사용할 수 있는 여러 메소드가 정의되어 있기 때문이다. 

 

물론 AbstractUser를 상속하지 않고도 유저 모델을 새로 정의해서 사용하는 것도 가능하다. 

 

하지만 이 경우 AbstractUser에 있던 기본 메소드들을 따로 정의해 주어야 하기 때문에 불편할 수도 있다. 

 

AbstractUser 모델을 상속해서 커스터마이징 할 경우, 다음과 같은 필드를 설정할 때는 주의해야 한다. 

 

USERNAME_FIELD

각 유저를 unique하게 인식하기 위해 필요한 필드이다. 이 값으로 선언한 필드는 반드시 unique 해야 한다. 

 

REQUIRED_FIELDS

createsuperuser 커맨드를 호출할 때는 이 필드들의 값을 모두 입력해야 한다. 이 필드값들은 unique 할 필요는 없지만 blank=False 이어야 한다. 

class CustomUser(AbstractUser):
	...
	email = models.CharField(max_length=40, unique=True)
    
	USERNAME_FIELD = "email"
	REQUIRED_FIELDS = ["email", "address"]

 

☑️blank와 null의 차이

null은 DB에 값을 저장할 때 null을 허용할지를 결정하고, blank은 DB와는 관련 없는 validation의 영역이다. null=True이어도 blank=False라면 DB에 넣을 값을 검사할 때 허용되지 않는다. 

 

그 외에도 AbstractBaseUser에는 세션이나 비밀번호 설정 등과 관련한 여러 메소드를 제공한다. 

 

is_authenticated

요청을 한 유저가 인증된 유저인지를 boolean 값으로 리턴한다. 

다만 이 값이 True라고 해도 이 유저가 어떤 특정 권한이 있거나 이 유저에 대한 세션이 있는지는 보장하지 않는다. 

 

set_password()

장고에서는 유저의 비밀번호 값을 그대로 저장하지 않고 암호화하여 저장하기 때문에 password의 값을 그대로 바꾸면 로그인이 되지 않는다. 

그 대신 set_password() 함수를 사용하면 해당 값이 암호화되어 저장된다. 

 

set_unusable_password()

장고에서 비밀번호를 사용하지 않을 때도 이 메소드를 사용하면 좋다. 

비밀번호에 공백 값을 넣는 것과 비밀번호를 사용하지 않는 것은 다른데, 이 메소드는 후자일 경우에 사용하자. 

 

get_session_auth_hash()

유저의 비밀번호를 HMAC 방식으로 암호화한 값을 리턴한다. (정확히 어떤 데 쓰이는지는 아직 모르겠다...)

 

 

☑️AbstractUser

만약 유저 모델의 특성을 거의 바꿀 것 같지 않다면 AbstractBaseUser를 상속한 AbstractUser 모델을 그대로 사용하는 것도 가능하다. 

 

이 모델에서는 USERNAME_FIELDREQUIRED_FIELDS 옵션도 이미 정의되어 있다.

 

AbstractBaseUser의 설정을 대부분 따르되 그 중 일부만 변경하고 싶다면 AbstractUser를 사용하면 코드를 간결하게 작성할 수 있다. 

class CustomUser(AbstractUser):
	pass

 

✅User manager Customizing

기본적으로, 각 모델에는 objects라는 이름을 가진 manager 클래스가 있다. 

 

이 manager 클래스는 모델이 어떤 쿼리를 통해서 데이터베이스와 어떻게 상호작용할지를 결정하는 일종의 인터페이스 역할을 한다. 

 

 

☑️BaseManager

 

유저 모델의 manager 클래스는 django.contrib.auth.models 모듈의 BaseManager 클래스를 상속한다. 

 

get_by_natural_key()

BaseManager에서 유저를 찾는 데 사용하는 메소드이다. 

createsuperuser 등의 커맨드에서도 호출된다. 

유저에서 USERNAME_FIELD로 선언한 필드의 값을 사용해서 유저를 찾는다.

 

 

☑️CustomManager

 

이 클래스를 상속해서 커스텀 manager 클래스를 만들고 싶다면 두 가지 메소드를 재정의해야 한다. 

 

create_user()

유저를 생성할 때 호출되는 메소드이다.

유저 모델에서 USERNAME_FIELDREQUIRED_FIELDS로 선언한 필드들은 모두 매개변수로 받아야 한다. 

 

create_superuser()

createsuperuser 커맨드를 사용할 때 호출된다. 

마찬가지로 USERNAME_FIELDREQUIRED_FIELDS로 선언한 필드들은 모두 매개변수로 받아야 한다. 

 

 

참고한 포스트

https://docs.djangoproject.com/en/5.0/ref/models/fields/#:~:text=null%20is%20purely%20database%2Drelated,the%20field%20will%20be%20required.

https://docs.djangoproject.com/en/5.0/topics/db/managers/

 

+ Recent posts