I am trying to implement django-allauth with a custom user model, but I keep getting errors when a new user is registering. The following is my User model:
# models.py
class User(AbstractUser):
name = models.CharField(_("Name of User"), blank=True, max_length=255)
tier = models.CharField(_("Plan"), choices=TIER_CHOICES, default='FREE', max_length=5)
dateOfBirth = models.DateField(_("Date of birth"), auto_now=False, auto_now_add=False)
gender = models.CharField(_('Gender'), choices=GENDER_CHOICES, default='MASC', max_length=5)
city = models.CharField(_("City"), max_length=100)
The fields on the model are to be completed by the user on Signup. To do this I have written a Custom Signup Form class, as per these instructions, which indicated the need for a signup() method:
# forms.py
class CustomSignupForm(SignupForm):
name = f.CharField(label=_("First Name"),
required=True,
widget=f.TextInput(attrs={'placeholder': _("First Name")})
)
dateOfBirth = f.DateField(label=_("Date of birth"),
required=True, initial='1990-01-01',
widget=f.DateInput()
)
city = f.CharField(label=_("City"),
required=True,
widget=f.TextInput(attrs={'placeholder': _("City")})
)
gender = f.ChoiceField(label=_("Gender"),
choices=GENDER_CHOICES,
required=True
)
def signup(self, request, user):
user.name = self.cleaned_data['name']
user.dateOfBirth = self.cleaned_data['dateOfBirth']
user.city = self.cleaned_data['city']
user.gender = self.cleaned_data['gender']
user.save()
return user
The same instructions also informed me I needed a custom allauth adapter (which is the basic allauth one but with the added fields such as dateOfBirth and city):
# adapter.py
class AccountAdapter(DefaultAccountAdapter):
def save_user(self, request, user, form, commit=False):
data = form.cleaned_data
user.email = data['email']
user.name = data['name']
user.dateOfBirth = data['dateOfBirth']
user.gender = data['gender']
user.city = data['city']
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
With this setup, I keep getting the same error (traceback):
save() prohibited to prevent data loss due to unsaved related object 'user'.
I have found a possible solution to this here and here, which is to add the save() method to the custom signup form:
# forms.py
class CustomSignupForm(SignupForm):
# ...
def save(self, user):
user.save()
When I try this, I get the following error (traceback):
AttributeError at /accounts/signup/ 'WSGIRequest' object has no attribute 'save'
I have also tried other solutions such as this. If anyone can point me in the right direction I would be grateful!
My settings.py config for django-allauth:
# settings.py (django-allauth)
ACCOUNT_ALLOW_REGISTRATION = env.bool("DJANGO_ACCOUNT_ALLOW_REGISTRATION", True)
ACCOUNT_AUTHENTICATION_METHOD = "email"
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
ACCOUNT_ADAPTER = "loteriai.users.adapters.AccountAdapter"
SOCIALACCOUNT_ADAPTER = "loteriai.users.adapters.SocialAccountAdapter"
ACCOUNT_FORMS = {'signup': 'loteriai.users.forms.CustomSignupForm'}
I am using the following packages:
Django Version: 3.1
Python Version: 3.8.3
django-allauth Version: 0.42.0