2025, Dec 09 11:00
Email-only login with dj-rest-auth and django-allauth: fix 'username is required' using django-allauth 65.2.0
Fix dj-rest-auth and django-allauth email-only login on a custom user model. Resolve username is required warnings by pinning django-allauth 65.2.0.
When wiring up dj-rest-auth and django-allauth for an email-only login flow on a custom user model, you may hit stubborn warnings and a confusing “username is required” response on login attempts. This guide shows what triggers it, why it happens with recent releases, and how to unblock your setup cleanly without changing your data model or API surface.
Problem overview
In a Django project that uses a custom user model with email as the identifier and aims to authenticate from a Next.js app via dj-rest-auth, the backend emits deprecation warnings coming from dj_rest_auth/registration/serializers and login may complain that username is required even though the username field was intentionally removed.
Repro code: custom user and settings
The scenario below mirrors the setup where the warnings pop up. The custom user removes username and relies on email, and the settings aim for email-only signup/login.
# models.py
import uuid
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import AbstractUser, PermissionsMixin, UserManager
class AccountBaseManager(UserManager):
def _spawn_user(self, full_name, email, password=None, **extra):
if not email:
raise ValueError('Users must have an email address')
email = self.normalize_email(email=email)
u = self.model(email=email, name=full_name, **extra)
u.set_password(password)
u.save(using=self.db)
return u
def create_user(self, full_name=None, email=None, password=None, **extra):
extra.setdefault('is_staff', False)
extra.setdefault('is_superuser', False)
return self._spawn_user(full_name=full_name, email=email, password=password, **extra)
def create_superuser(self, full_name=None, email=None, password=None, **extra):
extra.setdefault('is_staff', True)
extra.setdefault('is_superuser', True)
return self._spawn_user(full_name=full_name, email=email, password=password, **extra)
class Member(AbstractUser, PermissionsMixin):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
first_name = None
last_name = None
username = None
name = models.CharField(max_length=255)
email = models.EmailField(unique=True)
is_active = models.BooleanField(default=True)
is_superuser = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
avatar = models.ImageField(upload_to='avatars/', null=True, blank=True)
date_joined = models.DateTimeField(default=timezone.now)
last_login = models.DateTimeField(blank=True, null=True)
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = []
objects = AccountBaseManager()
def __str__(self):
return self.email
# settings.py (relevant bits)
AUTH_USER_MODEL = 'Users_app.Member'
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_LOGIN_METHODS = {'email'}
ACCOUNT_SIGNUP_FIELDS = ['email*', 'name*', 'password1*', 'password2*']
ACCOUNT_EMAIL_VERIFICATION = 'none'
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework.authtoken',
'allauth',
'allauth.account',
'allauth.socialaccount',
'dj_rest_auth',
'dj_rest_auth.registration',
]
AUTHENTICATION_BACKENDS = [
'allauth.account.auth_backends.AuthenticationBackend',
'django.contrib.auth.backends.ModelBackend',
]
REST_AUTH = {
'USE_JWT': True,
'JWT_AUTH_COOKIE': 'access_token',
'JWT_AUTH_REFRESH_COOKIE': 'refresh_token',
}
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
'rest_framework.authentication.SessionAuthentication',
],
}
What is actually going on
The warnings stem from recent django-allauth releases. A deprecation and a configuration check around login/signup fields were introduced, and messaging around them changed. In particular, a check validates alignment between login methods and signup fields and its severity level was adjusted.
A check is in place to verify that ACCOUNT_LOGIN_METHODS is aligned with ACCOUNT_SIGNUP_FIELDS. The severity level of that check has now been lowered from “critical” to “warning”, as there may be valid use cases for configuring a login method that you are not able to sign up with. This check (account.W001) can be silenced using Django’s SILENCED_SYSTEM_CHECKS.
Despite this, warnings persisted in newer versions. The practical resolution is to use an older django-allauth that does not exhibit the issue with the given configuration.
Solution that works reliably
Pin django-allauth to 65.2.0. Make sure your dependency file reflects the version and that your environment is rebuilt so the pin takes effect. If you run in Docker, rebuild your image after editing dependencies to ensure the downgrade is actually applied.
# requirements.txt (excerpt)
django-allauth==65.2.0
After pinning, use the following settings so email is the only authentication method and username is not required.
# settings.py (relevant bits after downgrading)
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_USERNAME_REQUIRED = False
This combination removes the pressure to provide a username and aligns the configuration with an email-only flow. If you previously saw a “username is required” response on login, verify that you downgraded the package effectively and restarted your stack. In containerized deployments, a simple reload is not enough; rebuild to pick up the new wheel. Also make sure the outdated version is not lingering in your environment by checking the resolved package versions.
Why this matters
Authentication is a cross-cutting concern for APIs, and tiny mismatches between packages and settings can break login and registration flows without changing any of your own code. Deprecation warnings from dependencies often signal behavior changes that surface as confusing validation errors. Aligning versions and settings ensures consistent behavior across environments, test runs, and CI pipelines.
Wrap-up and practical advice
If your dj-rest-auth and django-allauth integration raises deprecation warnings about username or email fields and pushes a “username is required” validation in an email-only setup, pin django-allauth to 65.2.0 and switch to the email-centric flags shown above. Confirm the downgrade via your dependency lock or requirements and rebuild your runtime if you use containers. Keep an eye on release notes when upgrading auth libraries; apply version pins proactively and adjust settings only after verifying behavior in a controlled environment.