4

So I have a project that uses a custom UserModel, the default UserModel is extended to use a Profile model with a OneToOne relation to the Usermodel.

I would like to use django allauth to verify emailaddresses and add social login.

I have some issues with the custom signup, I've read the following How to customize user profile when using django-allauth, but it's not entirely clear how to implement this, I get an error;

'GuestSignUpForm' object has no attribute 'save'

I've searched the forum and there seems to be no "official" documentation on how to do this, some people use ModelForms, others inherit from SignUpView, some def signup and others use def save...

I tried customizing the default UserModel with UserCreationForm and had no issues, I just need some clarification on the inner workings of the allauth package

models.py

# Custom Usermodel 
class User(AbstractUser):
    pass

# Custom Profile model to store additional info
class Profile(models.Model):
    prefix = models.CharField(_('prefix'), max_length=8, blank=True, default="")
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
    # Other fields left out for readability

    def __str__(self):
        if self.prefix:
            return '%s %s, %s' % (self.user.last_name, self.prefix, self.user.first_name)
        else:
            return '%s %s' % (self.user.last_name, self.user.first_name)

# Create a profile record on save
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
    else:
        instance.profile.save()

forms.py

from django import forms
from allauth.account.forms import SetPasswordField, PasswordField

from .models import User, Profile

class GuestSignUpForm(forms.Form):
    first_name = forms.CharField(max_length=30)
    prefix = forms.CharField(max_length=8, required=False)
    last_name = forms.CharField(max_length=150)
    email = forms.EmailField(required=True)
    password1 = SetPasswordField()
    password2 = PasswordField()

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()
        profile = Profile.objects.get(user=user)
        profile.prefix = self.cleaned_data.get['prefix']
        profile.save()
        return user
Kevin D.
  • 315
  • 2
  • 19
  • If you already have a custom user model, there's no need for the separate profile model! Just add the additional fields to the custom user model instead. – AKX Jan 17 '19 at 19:00
  • @AKX I really like the idea of just using the Django custom user model as the profile model for AllAuth, but do you think that the comment here, which states that you could end up generating migrations against the custom user model when you really don't need to, is a good argument against using the Django custom user model as the profile model for Allauth? https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html#comment-3451634529. I appreciate any feedback you provide as I'm pondering this option right now. – Dan Swain Jan 31 '19 at 14:46
  • That comment isn't really relevant for Allauth, as you've already "paid" the migration cost in `allauth.socialaccount`'s models/migrations. Things tend to Just Work even with Allauth if you have `AUTH_USER_MODEL` pointed at your custom AbstractUser-deriving model. – AKX Jan 31 '19 at 15:39
  • @AKX I think I understand, but would it be correct to restate the second sentence in this way: Things tend to Just Work with Allauth even if you have AUTH_USER_MODEL pointed at your custom AbstractUser-derived model and you are using this custom user model to store profile information that is saved by AllAuth. So the AllAuth setting ACCOUNT_FORMS = {'signup': 'app_name.forms.SignupForm'} would designate SignupForm which has: class Meta: model = get_user_model() – Dan Swain Jan 31 '19 at 17:17
  • Yup. So long as the fields Allauth expects to exist (username, email really) on your user model, you should be golden without an additional 1:1 model. – AKX Jan 31 '19 at 20:46

0 Answers0