Custom Register serializer not detected after switching from django-rest-auth
RomainFayolle opened this issue · comments
Hi !
I'm upgrading a project from Django 3.2.9 to 4.2.5, in a docker container.
Previous project requirements.txt
:
Django==3.2.9
djangorestframework==3.12.4
django-allauth==0.46.0
django-rest_auth==0.9.5
I upgraded to
Django==4.2.5
djangorestframework==3.14.0
django-allauth==0.58.1
dj-rest-auth==5.0.1
I switched to dj-rest-auth
as asked in django-rest-auth
https://github.com/Omaraitbenhaddi/django-rest-auth
I only changed the imports and the name usage of the packages and run a migrate
command.
Expected behavior: Project keep using CustomRegisterSerializer
as before
Actual behavior: Now, project ignore CustomRegisterSerializer
and uses regular RegisterSerializer
instead.
All resources online point to the settings,py
but I have the correct REST_AUTH_REGISTER_SERIALIZERS
(I even tried to put my serializer in REST_AUTH_SERIALIZERS
instead).
I also uninstalled and reinstalled allauth
. But keep getting the same issue:
File "/app/cloud_api/apps/user/adapters.py", line 13, in save_user
user.first_name = data['first_name']
KeyError: 'first_name'
Because wrong Serializer is used. Any idea of what I did wrong in the migration ?
serializers.py
from django.contrib.auth import get_user_model
from django.core.exceptions import ObjectDoesNotExist
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from dry_rest_permissions.generics import DRYGlobalPermissionsField
from dj_rest_auth.registration.serializers import RegisterSerializer
from dj_rest_auth.serializers import PasswordResetSerializer
User = get_user_model()
class CustomRegisterSerializer(RegisterSerializer):
first_name = serializers.CharField(
max_length=30,
allow_blank=True,
allow_null=True,
required=False
)
last_name = serializers.CharField(
max_length=150,
allow_blank=True,
allow_null=True,
required=False
)
password1 = serializers.CharField(write_only=True, required=False)
password2 = serializers.CharField(write_only=True, required=False)
def get_cleaned_data(self):
return {
'username': self.validated_data.get('username', ''),
'password1': self.validated_data.get('password1', ''),
'email': self.validated_data.get('email', ''),
'first_name': self.validated_data.get('first_name', ''),
'last_name': self.validated_data.get('last_name', ''),
}
def validate(self, data):
if 'password1' in data and data['password1'] != data['password2']:
raise serializers.ValidationError(
_("The two password didn't match."))
return data
adapaters.py
from allauth.account.adapter import DefaultAccountAdapter
from django.contrib.auth import get_user_model
User = get_user_model()
class AccountAdapter(DefaultAccountAdapter):
def save_user(self, request, user, form, commit=True):
data = form.cleaned_data
user.username = data['username']
user.email = data['email']
user.first_name = data['first_name']
user.last_name = data['last_name']
if 'password1' in data:
user.set_password(data['password1'])
else:
user.set_unusable_password()
self.populate_username(request, user)
if commit:
user.save()
return user
urls.py
urlpatterns = [
path(
'rest-auth/',
include('dj_rest_auth.urls')
),
path(
"password-reset/confirm/<uidb64>/<token>/",
TemplateView.as_view(template_name="password_reset_confirm.html"),
name='password_reset_confirm'
),
re_path(r'^accounts/', include('allauth.urls'), name='socialaccount_signup'),
path(
'rest-auth/registration/',
include('dj_rest_auth.registration.urls')
),
path('dj-rest-auth/facebook/', FacebookLogin.as_view(), name='fb_login'),
path('', include(router.urls)), # includes router generated URL
]
settings.py
INSTALLED_APPS = [
. . .
'dj_rest_auth',
'allauth',
'allauth.account',
'dj_rest_auth.registration',
'allauth.socialaccount',
'allauth.socialaccount.providers.facebook',
. . .
]
MIDDLEWARE = [
. . .
'allauth.account.middleware.AccountMiddleware',
]
ACCOUNT_ADAPTER = 'cloud_api'\
'.apps.user.adapters.AccountAdapter'
REST_AUTH_SERIALIZERS = {
'USER_DETAILS_SERIALIZER':
'cloud_api'
'.apps.user.serializers.UserSerializer',
'PASSWORD_RESET_SERIALIZER':
'cloud_api'
'.apps.user.serializers.CustomPasswordResetSerializer',
}
REST_AUTH_REGISTER_SERIALIZERS = {
'REGISTER_SERIALIZER':
'cloud_api'
'.apps.user.serializers.CustomRegisterSerializer'
}
I was able to get another project using the same requirements.
In fine, you have to merge your settings into a single var
REST_AUTH = {
'USER_DETAILS_SERIALIZER':
'cloud_api.apps.user.serializers.UserSerializer',
'OLD_PASSWORD_FIELD_ENABLED': True,
'PASSWORD_RESET_SERIALIZER':
'cloud_api.apps.user.serializers.CustomPasswordResetSerializer',
'REGISTER_SERIALIZER':
'cloud_api.apps.user.serializers.CustomRegisterSerializer',
'SESSION_LOGIN': False,
}