Building a MWE with email login and custom signup form: why is a custom adapter required? #4175
-
Hi all, I'm considering implementing Adding a custom user model to support email login is pretty easy, according to the documentation: ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_LOGIN_METHODS = {"email"}
ACCOUNT_EMAIL_VERIFICATION = "none" # Turned off for now Now let's say I have a custom app # my_project/my_app/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
is_awesome = models.BooleanField(default=False)
# my_project/settings.py
AUTH_USER_MODEL = "my_app.CustomUser" I also have a custom signup form # my_project/my_app/forms.py
from django import forms
from .models import CustomUser
class CustomUserCreationForm(forms.ModelForm):
class Meta:
model = CustomUser
fields = ("is_awesome", )
# Required by django-allauth
def signup(self, request, user):
pass
# my_project/settings.py
ACCOUNT_SIGNUP_FORM_CLASS = "my_app.forms.CustomUserCreationForm" Now, let's say I want to add 2 users to my database: from django.test import TestCase
from django.urls import reverse
class CustomUserCreationFormTest(TestCase):
def test_users(self):
form_data_1 = {
"email": "[email protected]",
"password1": "securepassword1",
"password2": "securepassword1",
"is_awesome": True,
}
form_data_2 = {
"email": "[email protected]",
"password1": "securepassword2",
"password2": "securepassword2",
"is_awesome": False,
}
# First signup attempt
response = self.client.post(reverse("account_signup"), data=form_data_1, follow=True)
self.assertEqual(response.status_code, 200)
# Logout
self.client.post(reverse("account_logout"), follow=True)
# Second signup attempt
response = self.client.post(reverse("account_signup"), data=form_data_2, follow=True) However, this tests fails with (full stack trace below)
The issue seems to be that I can fix the test by adding a custom adapter with a custom # my_project/my_app/adapter.py
from allauth.account.adapter import DefaultAccountAdapter
from allauth.account.utils import user_email, user_field
class CustomAccountAdapter(DefaultAccountAdapter):
# Use email as username
def populate_username(self, request, user):
email = user_email(user)
user_field(user, "username", email)
# my_project/settings.py
ACCOUNT_ADAPTER = "my_app.adapter.CustomAccountAdapter" Why is this adapter required? What am I missing? Full stack trace
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Your user model does have a
As a result, allauth won't make any attempt to populate it with a unique value. |
Beta Was this translation helpful? Give feedback.
Your user model does have a
username
field, yet, by configuring this you are informing allauth there is no such field:As a result, allauth won't make any attempt to populate it with a unique value.