mail 서비스를 도입해본다!
할일
1. welcome 메일 보내기
2. admin에 html 을 올리면 모든 활성사용자이자 메일을 받기로 한 유저에게 보내기 인데 메일 체크 여부가 없어서 일단 모든 활성 유저
일단 mail을 만들어봤는데
username 관련으로 db 를 살펴보기 위해.. admin 페이지로 갔더니 다음과 같은 에러가 떴다.
일단 다음에 해야지.. 비번을 잘못입력한건가... 일단 Csrf 관련 오류가 아니길 바라고 있다.
1 번 welcome 이메일을 보내는 와중에 이해못하는 에러가 발생했다.
그런데 왜인지 pytest 를 할 때 마다 device create 가 출력이 되지 않았다.
음 확인해보니 DoesnotExist 후에 바로 가장 바깥의 Exception 으로 가고 있었다.
왜지... 찾아봐야겠다..
찾아보니 일단 에러가 발생해서 처리된 후에도 밖에서 또 잡히는 것 같다.
그래서 이런식으로처리하지 말고 다른 식으로 처리해야될 것 같다.
일단 임시 방편으로 이런식으로 해결했다. 테스트에서 통과하면 바꿔야겠다.
또 이런 에러가 발생했다.
무슨에러인고하니..
html 은 templates 안에 속해야 찾을 수 있는 에러인듯하다. 그래서 폴더를 만들고 그 안에 파일을 넣어주었다.
Python/Django TemplateDoesNotExist 에러 처리 방법!!
최근 Django project를 하며 두들겨 맞고 있는데 이상하게 정말 자주 보이는 에러가 있다! Django에 대해 잘 몰라서 발생하는 경우가 많았는데 오늘은 간략하게 이 에러에 대한 대처 방법을 다뤄보려
june98.tistory.com
그랬더니 잘 해결되었다!
테스트 코드는 다음과 같다.
@pytest.mark.django_db
class TestGoogleLogin:
@pytest.fixture
def api_client(self):
return APIClient()
@patch("accounts.views.id_token.verify_oauth2_token")
@patch("accounts.views.send_email") # Ensure the correct patch path
def test_google_login_new_user(
self, mock_send_email, mock_verify_oauth2_token, api_client
):
# Mock the token verification response
mock_verify_oauth2_token.return_value = {
"iss": "accounts.google.com",
"email": "testuser@example.com",
}
# Define the URL for the GoogleLogin view
url = reverse(
"google_login"
) # Replace 'google-login' with your actual URL name
# Create a mock request
data = {"token": "mock_token", "device_token": "mock_device_token"}
# Call the view
response = api_client.post(url, data, format="json")
print(response.data)
# Check that the user was created
user = User.objects.get(username="testuser@example.com")
assert user is not None
# Check that the device was created
device = Device.objects.get(user_id=user.id, token="mock_device_token")
assert device is not None
# Check that the email was sent
mock_send_email.assert_called_once_with(
"계정이메일@gmail.com",
"Welcome to join us",
welcome_email(user.username),
)
# Check the response status
assert response.status_code == status.HTTP_200_OK
assert "refresh" in response.data
assert "access" in response.data
잘 통과했다.
이제 뷰를 좀 리팩토링해본다.
class GoogleLogin(APIView):
google_client_id = settings.SECRETS.get("GCID")
authentication_classes = []
permission_classes = [AllowAny]
def post(self, request):
token = request.data.get("token")
device_token = request.data.get("device_token")
if not device_token or not token:
raise Exception("device token and token is required")
try:
idinfo = id_token.verify_oauth2_token(
token, requests.Request(), audience=GOOGLE_CLIENT_ID
)
if "accounts.google.com" in idinfo["iss"]:
email = idinfo["email"]
user = self.get_or_create_user(email)
Device.objects.get_or_create(user_id=user, token=device_token)
refresh = CustomRefreshToken.for_user(user, device_token)
return Response(
{
"refresh": str(refresh),
"access": str(refresh.access_token),
}
)
except Exception:
return Response(status=status.HTTP_400_BAD_REQUEST)
def get_or_create_user(self, email):
try:
user = User.objects.get(username=email, password="")
except User.DoesNotExist:
user = User.objects.create(username=email, password="")
send_email(
"확인용이메일@gmail.com",
"Welcome to join us",
welcome_email(user.username),
)
return user
함수로 처리하니 깔끔해졌다.
일단 이정도로 하면 될 것 같다.
2번 문제인 메일을 작성하면 사용자 모두에게 전달하는 로직을 만들어본다.
일단 생각중인 것은 admin 페이지에 html 파일을 올리면 보낼 수 있도록 하는 로직을 생각하고 있다.
그러니 일단 admin 에 파일을 올리기, 버튼을 누르면 해당 함수를 호출하도록 수정하기를 진행하면 될 것 같다.
아주 간단하게 admin 페이지에 html 을 올리면 바로 모든 사용자에게 보내는 로직을 짜본다
이런식으로 작성한 후에 admin 에 등록해주었다.
저기 이메일을 팀 이메일로 했을 때는 잘 동작을 했다.
그러나 문제가 발생했는데 그 이유는 다음과 같았다.
이런 오류가 발생했다.
도메인 관련 문제라고 생각하는데 들어가보니 도메인 verification 이 실패되어 있었다.
그래서 다시 도메인을 확인하도록 변경해본다. 그런데 이게 5시간 정도 걸릴 수 있다고 해서 일단 진행해보고 내일도 fail 이 떠있으면 원인을 파악하고 안되면 다른 곳으로 옮기는 편이 나을 것 같다. 그리고 추가적으로 도메인이 완료가 되면 보내는 송신 이메일도 변경해야한다.
그리고 우리팀은 아직 api 횟수 제한을 넣지 않은 상태라 이것을 넣어보려고 한다.
에 잘 정돈된 정리글이 있길래 확인해주었다.
일단 횟수제한은 가장 기본적인 내용이기 때문에 지원되는 곳은 없는지 확인해보려고 한다.
조건은 다음과 같은데 django나 aws에서 지원이 되면 일단 이걸로 갈 예정이다, 아직 규모가 크지 않기 때문에 비용이 저렴한 것으로 사용할 예정이며 같은 비용이면 레퍼런스가 많은 곳을 사용하려고한다.
찾았던 블로그글에서는 bucket4j 를 사용하는 것 같길래 한번 찾아봤다.
"" Bucket4j는 Token bucket 알고리즘을 기반으로 하는 Java 속도 제한 라이브러리 입니다. ""
그러므로 파이썬에 맞는 라이브러리를 찾으러 가보겠다...
https://hunstory.tistory.com/72
[Django] 스로틀링(Throttling) - 요청 속도 제어
목차 스로틀링(Throttling) 이란? 클라이언트가 API에 보낼 수 있는 요청 속도를 제어 할 수 있게 해준다. Request가 안정적인 상태의 요청 속도 및 버스트 한도를 초과할 경우, 요청을 실패시키고 "429 T
hunstory.tistory.com
여기를 확인해보니 django 자체에서 지원하는 것 같다.
일단 더 찾아봐보면 될 것 같다.
이쪽을 찾아보니 우리 모델에 문제가 발생했다.
1. 유료유저인지 무료유저인지 모름 (속성이 없음)
2. 이메일을 보내도 되는지 확인 안하고 있음
3. 프론트쪽에 결제하는 창이 없음
그래서 일단 모든 유저에게 프리미엄으로 해놓아야할 듯 하다.
일단 model 부터 변경할 필요가 있어보인다.
'소프트웨어 마에스트로 > BackEnd(Django)' 카테고리의 다른 글
[Django] refactoring 진행기 1 + custom exception (0) | 2024.09.24 |
---|---|
[Django] mail service 도입기 3 (2) | 2024.09.23 |
[컨퍼런스 후기] toss slash24 + gencon (4) | 2024.09.20 |
[django] mail service 도입기 (0) | 2024.09.11 |
[Django] Customer Support 창 만들기 (0) | 2024.09.10 |