问题
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.
回答1:
ok, after trying many different posted solutions, I found something that works. I'm not exactly sure why, so I would love an explanation if anyone has it, but I'm posting this here in case someone else comes along with a similiar problem and just wants the solution.
This is what my end signupform form looked like:
class CustomSignupForm(SignupForm):
user_type = forms.CharField(
widget=forms.Select(choices=USER_TYPE_CHOICES))
class Meta:
model = User
def save(self, request):
user = super(CustomSignupForm, self).save(request)
user.user_type = self.cleaned_data['user_type']
user.save()
return user
instead of including a signup() function it looks like you need to use def save(self, request):
as signup is (I think) deprecated. Then you need to add user = super(MyCustomSignupForm, self).save(request)
as is mentioned in the docs here. That's the part I really don't understand but there it is. I'll try to remember to come back and edit this if I figure it out.
回答2:
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!
来源:https://stackoverflow.com/questions/63430747/django-allauth-signup-form-not-saving-custom-fields