Multiple Sign Up Forms Allauth

I recently created a Django template using allauth for an Abstract User.

I followed William Vincent’s best practices in his book and the settings according to the documentation but I’m currently stuck.

I’d like to support multiple sign up forms to create a user. The 2 sign up forms I’d like to support are:

  1. Account creation, which uses the typical convention of:
# my_project/setings.py
AUTH_USER_MODEL = 'users.CustomUser'
LOGIN_REDIRECT_URL = 'home'
LOGOUT_REDIRECT_URL = 'home'
ACCOUNT_SESSION_REMEMBER = True
ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE = False
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_USER_MODEL_USERNAME_FIELD = 'username'
ACCOUNT_USER_MODEL_EMAIL_FIELD = "email"
  1. A User Subscription Form (with simply email and no password), which uses what I came up with:
# users/forms.py
class CustomUserSubscribeForm(forms.ModelForm):
    class Meta:
        model = CustomUser
        fields = ('email', )
        
    email = forms.EmailField(
        label=_(''),
        widget=forms.TextInput(
                attrs={
                    'placeholder': _('john@email.com')
                }
             )
        )
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper =  FormHelper()
        self.helper.form_show_labels = False
        self.helper.form_method = 'POST'
        self.helper.form_class = 'form-inline justify-content-center'
        self.helper.layout = Layout(
            Div(
                FieldWithButtons('email', Submit('Submit', 'submit', css_class='btn btn-outline primary')),
                Submit('submit', u'Submit', css_class='btn btn-success'),
                css_class='form-inline'
            )
        )
# users/views.py
class SubscribePageView(CreateView):
    form_class = CustomUserSubscribeForm
    success_url = reverse_lazy('subscribe')
    template_name = 'subscribe.html'
# users/urls.py
from .views import SubscribePageView
urlpatterns = [
    path('subscribe', SubscribePageView.as_view(), name='subscribe'),  
]

These views/html pages render but the issue I’m facing is when I try to use the Subscription form, I receive an integrity error:

duplicate key value violates unique constraint "users_customuser_username_80452fdf_uniq"
DETAIL:  Key (username)=() already exists.

Any help/guidance would be much appreciated here as I’ve been trying to handle this a million different ways for the past week. Thank you!

Part of your problem is that Django still requires unique usernames behind the scenes even if they’re not actually used to authenticate and you just use emails. Presumably you have already added one user with an empty username, and when you come to the next one, you can’t.

I am not sure what the solution with allauth is because I’ve not used it, but e.g. django-social-auth will generate its own unique username if required. You will definitely need some slightly more sophisticated logic in your CreateView to handle this, perhaps subclassing something in allauth, I don’t know.

PS. Please enclose code blocks in triple back quotes (```) - it makes it much easier to read!

2 Likes

Thank you! I updated the post with triple blocks!

Separately I assumed using the allauth configuration of ACCOUNT_USER_MODEL_EMAIL_FIELD = "email" would handle it, but I guess that wasn’t the case.

Thanks so much for the advice!