Django 로 개발을 하던 중 auth 라는 이름을 가진 Custom app을 INSTALLED_APP에 추가하니 오류가 발생했다.

기존의 "django.contrib.auth" 앱과 중복되었기 때문이다.

 

 

https://code.djangoproject.com/ticket/21562

 

#21562 (Bad things happen if you name your custom user app "auth") – Django

Bad things happen if you name your custom user app "auth" Reported by: Charlie DeTar Owned by: nobody Component: Documentation Version: dev Severity: Normal Keywords: Cc: Triage Stage: Accepted Has patch: yes Needs documentation: no Needs tests: no Patch n

code.djangoproject.com

새로운 이름으로는 accounts가 적절 할 것 같다.

이름 변경 후에 users 앱과 통합시켜야 겠다.

 

깃허브 링크

https://github.com/Doran-Doran-development/DoranDoran-Server-2

 

Doran-Doran-development/DoranDoran-Server-2

🧮 교내 실습실 예약 및 관리 웹 서비스 '도란도란'의 서버를 개발한 레포지토리 입니다. Contribute to Doran-Doran-development/DoranDoran-Server-2 development by creating an account on GitHub.

github.com

 

Django로 이메일 전송을 구현하고 있는데 send_mail 함수에서 위와 같은 오류가 났다.

 

위 오류의 내용은 send_mail의 매개변수 from_email을 안 넘겨 줬다는 소리다.

from django.core.mail import send_mail


send_mail(
	subject="Activate your DoranDoran account.",
	message="Please Activate your account http://localhost:8000",
	recipient_list=[user_instance.user.email],
	fail_silently=False,
)

코드는 위와 같았는데, from_email 이 없다고 오류가 난다.

그런데 django.core.mail.send_mail 의 소스코드를 보면 아래와 같이 설명되어 있다.

If from_email is None, user the DEFAULT_FROM_EMAIL setting.

45번째 줄을 보면 from_email 이 None이면 DEFAULT_FROM_EMAIL을 사용한다고 되어있다. 하지만 같이 써있는 auth_user는 기본값 None이 있는 반면, from_email을 기본값이 설정되어 있지 않다. 그래서 적어주지 않으니 오류가 발생하는 것이다.

 

결국 해결방법은 from_email을 적어주면 된다.

from django.core.mail import send_mail


send_mail(
	subject="Activate your DoranDoran account.",
	message="Please Activate your account http://localhost:8000",
	from_email=None,
	recipient_list=[user_instance.user.email],
	fail_silently=False,
)

이렇게 하면 해결되긴 하지만 django 라이브러리에 일관성이 없다고 생각이 든다... PR 보내봐야 겠다.

 

========================================

 

PR 보내고 봤더니 이미 이전에 있었던 이슈였다.

https://code.djangoproject.com/ticket/32633#comment:3

 

#32633 (send_mail must make `from_email` argument optional) – Django

the django docs state that, while sending mail, if no from_email is passed, it will use the DEFAULT_FROM_EMAIL. source: ​https://docs.djangoproject.com/en/3.1/topics/email/ from_email: A string. If None, Django will use the value of the DEFAULT_FROM_EMAI

code.djangoproject.com

Django 이메일 verification을 구현하다가 소스를 까봤는데 아래와 같은 코드가 나왔다.

# django/core/mail/message.py

class EmailMessage:
    """A container for email information."""
    content_subtype = 'plain'
    mixed_subtype = 'mixed'
    encoding = None     # None => use settings default

    def __init__(self, subject='', body='', from_email=None, to=None, bcc=None,
                 connection=None, attachments=None, headers=None, cc=None,
                 reply_to=None):
        """
        Initialize a single email message (which can be sent to multiple
        recipients).
        """
        if to:
            if isinstance(to, str):
                raise TypeError('"to" argument must be a list or tuple')
            self.to = list(to)
        else:
            self.to = []
        if cc:
            if isinstance(cc, str):
                raise TypeError('"cc" argument must be a list or tuple')
            self.cc = list(cc)
        else:
            self.cc = []
        if bcc:
            if isinstance(bcc, str):
                raise TypeError('"bcc" argument must be a list or tuple')
            self.bcc = list(bcc)
        else:
            self.bcc = []

여기서 나오는 to, cc, bcc 가 무엇인지 몰라 무엇을 위한 코드인지 이해하기 어려웠다. 

기본 상식이 부족한게 너무 아쉬웠다...

To (수신인 = 받을 사람)

이메일을 직접적으로 받을 사람을 적는 공간이다.

Cc (참고할 사람)

이메일의 작업을 직접적으로 수행하지 않을 사람이지만, 해당 내용을 참고하라고 알려주고 싶은 사람을 적는 공간이다.

예를 들자면 A가 B에게 "작업을 모두 끝냈어요!" 라고 메세지를 보내고, Cc로 팀장을 지정하면 팀장은 그 메일을 참고해서 작업의 진척도가 어느 정도인지 확인 할 수 있을 것이다.

 

Carbon Copy의 약자이다.

Bcc (참고할 사람 숨기기)

위의 cc와 같이 해당 내용을 참고하라고 알려주고 싶은 사람을 적는 공간이다.

하지만 cc의 경우는 이메일을 받는 사람 모두 to와 cc가 누구인지 알 수 있게 된다.

내가 누구를 cc로 지정했는지 숨기고 싶다면 bcc에다가 적으면 된다.

 

 

 

문제 풀이 코드

def solution(board, moves):
    answer = 0
    result_stack = []

    for move in moves:
        for i, column in enumerate(board):
            if column[move - 1] != 0:
                if len(result_stack) > 0:
                    if (recent := result_stack.pop()) == column[move - 1]:  #1
                        answer += 2
                        board[i][move - 1] = 0
                        break
                    else:
                        result_stack.append(recent)
                result_stack.append(column[move - 1])
                board[i][move - 1] = 0
                break

    return answer

#1

왈러스 연산자를 사용해서 pop 한 값(recent)을 if else 네임스페이스에서 사용할 수 있도록 했다.

wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
echo deb http://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list

apt-get update
apt-get install jenkins

 

문제 풀이 코드

def solution(a, b):
    return sum([x*y for x,y in zip(a, b)])

졸리고 머리아파서 그냥 1단계 풀었다.

아이디어

DFS 문제이다.
예를 들어numbers : [ 1, 1, 1 ],target : 1이 들어왔다면 아래와 같은 이진 트리 구조를 갖는다.

노드의 종점에서 target 값과 비교해 같다면 answer에 +1을 해주는 것이다.

문제 풀이 코드

def solution(numbers, target):
    answer = 0
    def dfs(current_total, current_index, sign): # dfs(0,0,1)
        nonlocal answer

        current_total += numbers[current_index] * sign 

        if len(numbers) <= current_index + 1: # 1
            if current_total == target:
                answer += 1
        else: # 2
            dfs(current_total, current_index + 1, 1)
            dfs(current_total, current_index + 1, -1)
        return

    dfs(0,0,1)
    dfs(0,0,-1)
    return answer

#1

다음 인덱스가 존재하지 않을 때 (노드의 종점일때 )

#2

다음 인덱스가 존재 할 때 (노드의 종점이 아닐 때)

네임스페이스란?

네임스페이스란 프로그래밍 언어에서 특정한 객체를 이름에 따라 구분할 수 있는 공간을 의미한다.

my_string = "asdf"



my_integer = 12



my_list = [1,2,3]

my_list2 = my_list

위 예시에서는 my_string"asdf"객체를 가리키고 있다.

위와 같이 이름과 객체를 연결한 것을네임스페이스 라고 한다.

왜 필요한데?

프로그래밍을 하다보면 모든 변수와 함수명을 겹치지 않도록 하는 것은 불가능 하다.

그렇기 때문에 특정한 이름의 변수 혹은 함수가 통용될 수 있는 범위를 제한하기 위해 네임스페이스가 등장한 것이다.

아래의 코드를 보자

class TestA:

    a = 1



class TestB:

    a = 2

a라는 변수이름이 중복되어 사용되고 있다. 만약 네임스페이스라는 개념이 없다면 원하는 a를 호출하기 힘들 것이다.

TestA 라는 로컬 네임스페이스에서 a를 호출하면 1의 값을 가진 변수 a를 얻을 수 있고,

TestB 라는 로컬 네임스페이스에서 a를 호출하면 2의 값을 가진 변수 a를 얻을 수 있게 된다.

Local, Global, Built-in Namespace

앞서 말했듯이 네임스페이스는 변수 혹은 함수가 통용될 수 있는 범위를 제한하기 위해 등장했다.

이런 네임스페이스는 Local, Global, Built-in 3가지로 분류할 수 있다.

  • Build-in
    기존 내장 함수 들의 이름이 소속된다. 파이썬으로 작성 된 모든 범위가 포함된다.

  • Global
    모듈별로 존재하며, 모듈 전체에서 통용될 수 있는 이름들이 소속된다.

  • Local
    함수 및 메서드 별로 존재하며, 함수 내의 지역 변수들의 이름들이 소속된다.

+ Recent posts