I'm trying to do something that should be very simple: adding a field to signup and saving it to my user object. I am using allauth, so the way this is supposed to be done as far as I can tell is by modifying the allauth form for signup. I've followed the instructions here: How to customize user profile when using django-allauth:
This is what my forms.py looks like:
from allauth.account.forms import SignupForm
from django import forms
UNASSIGNED = 'NA'
CLIENT = 'CL'
USER_TYPE_CHOICES = (
(UNASSIGNED, 'Unassigned'),
(CLIENT, 'Client'),
)
class CustomSignupForm(SignupForm):
user_type = forms.CharField(
widget=forms.Select(choices=USER_TYPE_CHOICES))
def signup(self, request, user):
user.user_type = self.cleaned_data['user_type']
user.save
return user
and then my custom user:
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=254, unique=True)
name = models.CharField(max_length=254, null=True, blank=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
UNASSIGNED = 'NA'
CLIENT = 'CL'
USER_TYPE_CHOICES = (
(UNASSIGNED, 'Unassigned'),
(CLIENT, 'Client'),
)
user_type = models.CharField(max_length=2,
choices=USER_TYPE_CHOICES,
default=UNASSIGNED)
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
def get_absolute_url(self):
return "/users/%i/" % (self.pk)
I know that the field that I added to the user works as I can see it in the admin and access it in the shell. The form renders properly (I can see the drop down for the new field.) The problem is that the form never saves the new user_type field, it always shows up as unassigned. I would greatly appreciate any advice on troubleshooting! I've been working on this a while and I haven't found any threads with the same issue.
I did have the same challenge when I was starting using Allauth. The main difference is that Allauth uses the DefaultAccountAdapter to handle the save_user logic. This is where super comes in. As mentioned in this SO post you call the Parent's save function together with your own save function when using super. When not calling super here the custom fields never get passed into the adapter. Try discovering the DefaultaccountAdapter by writing your own custom one:
custom_adapter.py
class CustomAccountAdapter(DefaultAccountAdapter):
# your custom logic
return user #or whatever your user model is called
And don't forget to put it into your settings:
ACCOUNT_ADAPTER = 'yourappname.custom_adapter.CustomAccountAdapter'
Happy coding!