본문 바로가기
프로젝트/MMOP(추천시스템_최종프로젝트)

이메일 인증

by 수쨔앙 2022. 12. 7.

AttributeError: 'NoneType' object has no attribute '_meta'

 

자꾸 이 에러가 나는데 문제는

from django.contrib.auth.models import User
from django.contrib import auth

 

얘를 임포트해왔기 때문이다

 나는 이미 위에 users.models import User라고 User를 임포트 해왔는데

또 임포트하니까 에러가 난 것.... 젠장........

 

 

 

TypeError: a bytes-like object is required, not 'str'

 

이 에러는 bytes-likes 오브젝트가 필요하니 str 타입 말고 bytes 타입의 변수를 넣으라는 뜻

message = render_to_string('users/account_activate_email.html', {
            'user': user,
            'domain': 'localhost:8000',
            'uid': urlsafe_base64_encode(force_bytes(user.pk)),
            'token': account_activation_token.make_token(user),
        })
class UserEmailVaild(APIView):
    permission_classes = (permissions.AllowAny, )
    def get(self, request, uidb64, token):
        try:
            uid = force_str(uidb64.encode('utf-8'))

 

 

 

django.urls.exceptions.NoReverseMatch: 'user' is not a registered namespace

 

users/urls.py에  

app_name = 'users' 안적어줬기 때문

더보기

해당 문제는 reverse 나 reverse_lazy 와 같이 redirect 경로를 찾아주는 함수에서 발생하는 에러 같습니다.

accountapp:detail 이런 형식으로 강좌 내에서 다시 재연결 시켜주는 과정을 진행했죠.

그런데 해당 에러를 살펴보면 accountapp 이라는 namespace, 그러니까 명칭이 설정되어있지 않은것으로 보입니다.

accountapp 내부에 urls.py 파일 상단에

app_name = "accountapp" 

이라는 선언을 해주셔야, 

reverse('accountapp:detail') 과 같은 구문을 사용했을때, 

정상적으로 accountapp 내부에 있는 detail 경로에 해당하는 url을 반환할 수 있게 됩니다.

accountapp 내부의 urls.py 파일 안에

app_name = "accountapp" 

구문이 있는지 확인해보시는게 좋을것 같습니다.

 

 

django.urls.exceptions.NoReverseMatch: Reverse for 'activate' not found. 'activate' is not a valid view function or pattern name.

 


 

django.urls.exceptions.NoReverseMatch: Reverse for 'activate' with keyword arguments '{'uid64': 'MQ', 'token': 'bg2npy-79d060fbf41e87482b5b3949a5a6f256'}' not found. 1 pattern(s) tried: ['users/activate/(?P<uidb64>[^/]+)/(?P<token>[^/]+)\\Z']

 

회원가입 링크 : http://{{ domain }}{% url 'users:activate' uid64=uid token=token %}

회원가입 링크 : http://{{ domain }}{% url 'users:activate' uidb64=uid token=token %}

 

오타.........

 


이메일 인증 encode/decode시 발생하는 문제

back에서 회원가입 시 인증 이메일을 전송 할 때 uid를 decode 하려했는데

AttributeError: 'str' object has no attribute 'decode' 에러가 발생했다.

 

users/serializers.py

 

 

 

해당 에러는 이미 decode가 되었기 때문에 decode할게 없어서 발생한 에러였다.

django 공식문서를 찾아보니 urlsafe_base64_encode를 보면 이미 decode를 해서 반환해준다

def urlsafe_base64_encode(s):
    """
    Encode a bytestring to a base64 string for use in URLs. Strip any trailing
    equal signs.
    """
    return base64.urlsafe_b64encode(s).rstrip(b"\n=").decode("ascii")

 

decode를 할 게 없었던 것이므로 해당 코드 줄의 .decode('utf-8') 부분을 지웠더니

해당 에러는 해결되고 AttributeError: 'bytes' object has no attribute 'encode' 에러가 발생했다

 

후딱 해당 부분으로 가보니

 

users/views.py

 

 

이 경우도 마찬가지로 이미 아래와 같이 encode가 되어있는 상태에서 encode를 또 해주려고 해서 발생한 동일한 오류!

def urlsafe_base64_decode(s):
    """
    Decode a base64 encoded string. Add back any trailing equal signs that
    might have been stripped.
    """
    s = s.encode()
    try:
        return base64.urlsafe_b64decode(s.ljust(len(s) + len(s) % 4, b"="))
    except (LookupError, BinasciiError) as e:
        raise ValueError(e)

 

해당 부분 지워주면서 해결!

 


AssertionError: Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be returned from the view, but received a `<class 'NoneType'>`

 

class UserEmailVaild(APIView):
    permission_classes = (permissions.AllowAny, )
    def get(self, request, uidb64, token):
        try:
            uid = force_str(urlsafe_base64_decode(uidb64))
            user = User.objects.get(pk=uid)
        except(TypeError, ValueError, OverflowError, User.DoesNotExist):
            user = None

        try:
            if user is not None and account_activation_token.check_token(user, token):
                user.email_valid = True
                user.save()
                return Response(user.data , status=status.HTTP_200_OK)
        except:
            return Response({'message':'땡탈락'}

 

각각의 예외처리를 안해줬기 때문

 

 class UserEmailVaild(APIView):
    permission_classes = (permissions.AllowAny, )
    def get(self, request, uidb64, token):
        try:
            uid = force_str(urlsafe_base64_decode(uidb64))
            user = User.objects.get(pk=uid)
        except(TypeError, ValueError, OverflowError, User.DoesNotExist):
            user = None

        try:
            if user is not None and account_activation_token.check_token(user, token):
                user.email_valid = True
                user.save()
                return Response(user.data , status=status.HTTP_200_OK)
            else:
                return Response('만료된 링크입니다.', status=status.HTTP_400_BAD_REQUEST)
        except:
            return Response({'message':'땡탈락'}

 

예외처리해주고 해결!

728x90

댓글