이번 프로젝트에서는 drf와 react를 사용하고, 로그인 회원가입 기능도 dj-rest-auth와 alllauth를 사용해서 구현한다.
drf를 처음 사용해봐서 지금 당장은 어려움이 있지만 또 하다보면 익숙해진다고 생각하고 열심히 해봐야겠다!
우선 models.py부터 보자!
여기선 다양한 필드를 받아야 하기 때문에 AbstractUser를 상속해서 유저를 확장해줬다.
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
username = None
email = models.EmailField(max_length=255, unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
realname = models.CharField(max_length=50, blank=True)
nickname = models.CharField(max_length=50, blank=True)
address = models.CharField(max_length=200, blank=True)
phone = models.CharField(max_length=100, blank=True)
height = models.DecimalField(max_digits=4, decimal_places=1, default=0)
weight = models.DecimalField(max_digits=4, decimal_places=1, default=0)
def __str__(self):
return self.email
다음은 urls.py이다. 다른 경로는 신경안써도 되고 dj-rest-auth부분만 보면 된다.
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('dj-rest-auth/', include('dj_rest_auth.urls')),
path('dj-rest-auth/registration/', include('dj_rest_auth.registration.urls')),
path('accounts/', include('allauth.urls')),
path('accounts/', include('accounts.urls')),
]
다음은 대망의 serializers.py이다.
serializer는 간단하게 말하면 장고의 form과 비슷한데, 데이터를 직렬화해서 json형식으로 넘겨주는 녀석이다!
나는 우선 기본 serializers를 상속받아서 SignUpSerializer를 만들어주고, 그 안에 get_cleaned_data()와 save() 메소드를 오버라이딩했다.
오버라이딩할때 상속받은 클래스는 dj-rest-auth 공식 github에서 참고했다.
또, 공식 문서에서도 관련 내용을 확인할 수 있다.
https://django-rest-auth.readthedocs.io/en/latest/configuration.html
from .models import User
from rest_framework import serializers
from django.core.exceptions import ValidationError as DjangoValidationError
from allauth.account.adapter import get_adapter
class SignUpSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['email', 'password', 'realname', 'nickname', 'address', 'phone', 'height', 'weight']
def get_cleaned_data(self):
return {
'realname': self.validated_data.get('realname', ''),
'password': self.validated_data.get('password', ''),
'email': self.validated_data.get('email', ''),
'nickname': self.validated_data.get('nickname', ''),
'address': self.validated_data.get('address', ''),
'phone': self.validated_data.get('phone', ''),
'height': self.validated_data.get('height', ''),
'weight': self.validated_data.get('weight', ''),
}
def save(self, request):
adapter = get_adapter()
user = adapter.new_user(request)
self.cleaned_data = self.get_cleaned_data()
user = adapter.save_user(request, user, self, commit=False)
if "password" in self.cleaned_data:
try:
adapter.clean_password(self.cleaned_data['password'], user=user)
except DjangoValidationError as exc:
raise serializers.ValidationError(
detail=serializers.as_serializer_error(exc)
)
user.save()
return user
다음은 adapters.py인데 adapter는 allauth의 클래스이다.
자세한 내용은 공식문서에서 확인할 수 있다.
https://django-allauth.readthedocs.io/en/latest/installation.html
from allauth.account.adapter import DefaultAccountAdapter
class CustomAccountAdapter(DefaultAccountAdapter):
def save_user(self, request, user, form, commit=True):
data = form.cleaned_data
# 기본 저장 필드: username, email
user = super().save_user(request, user, form, False)
# 추가 저장 필드: realname, nickname, address, phone, height, weight
realname = data.get('realname')
nickname = data.get('nickname')
address = data.get('nickname')
phone = data.get('phone')
height = data.get('height')
weight = data.get('weight')
if realname:
user.realname = realname
if nickname:
user.nickname = nickname
if address:
user.address = address
if phone:
user.phone = phone
if height:
user.height = height
if weight:
user.weight = weight
user.save()
return user
그리고 settings.py 에서도 관련된 설정들을 해줘야 한다.
AUTH_USER_MODEL = 'accounts.User'
REST_AUTH_REGISTER_SERIALIZERS = {
'REGISTER_SERIALIZER': 'accounts.serializers.SignUpSerializer'
}
ACCOUNT_ADAPTER = 'accounts.adapters.CustomAccountAdapter'
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
],
}
이렇게 해서 dj-rest-auth와 allauth를 사용한 회원가입기능을 구현해봤다.
'django, drf' 카테고리의 다른 글
timezone설정이 일부 datetime_field에만 적용되는 이슈 해결방법 (0) | 2022.11.17 |
---|---|
drf dj_rest_auth 로그인 커스텀, non_field_error 해결방법 (0) | 2022.11.17 |
사용한 라이브러리 관리 (0) | 2022.07.28 |
내가 보려고 쓰는 장고 설치+초기설정 (0) | 2022.04.04 |