title: Django: add user on admin page using custom user model
body: <p>I defined a custom user model in my Django project, which defines the 'email' as the unique identifier. I created a custom user creation form following the Django documentation and registered it in my admin.py. When I start the web server, no errors are shown in the console.</p>
  <p>My problem is, that the <code>add_form</code> on the admin page does not show the 'email' field, but only 'username', 'password1' and 'password2'</p>
  <p>I read several how to's and tutorials and checked the Django documentation to resolve this issue and am afraid I am missing something.</p>
  <h1>settings.py</h1>
  <pre><code># Application definition
  
  INSTALLED_APPS = [
      'django.contrib.admin',
      'django.contrib.auth',
      'django.contrib.contenttypes',
      'django.contrib.sessions',
      'django.contrib.messages',
      'django.contrib.staticfiles',
      'users.apps.UsersConfig'
  ]
  
  AUTH_USER_MODEL = 'users.NewUser'
  </code></pre>
  <h1>model.py</h1>
  <pre><code># Custom User Account Model
  
  from django.db import models
  from django.utils import timezone
  from django.utils.translation import gettext_lazy as _
  from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
  
  
  class CustomAccountManager(BaseUserManager):
      &quot;&quot;&quot;
      Custom user model manager where email is the unique identifiers for authentication instead of usernames.
      &quot;&quot;&quot;
      def create_user(self, email, username, first_name, last_name, password=None, **other_fields):
          if not last_name:
              raise ValueError(_('Users must have a last name'))
          elif not first_name:
              raise ValueError(_('Users must have a first name'))
          elif not username:
              raise ValueError(_('Users must have a username'))
          elif not email:
              raise ValueError(_('Users must provide an email address'))
  
          user = self.model(
              email=self.normalize_email(email),
              username=username,
              first_name=first_name,
              last_name=last_name,
              **other_fields
          )
          user.set_password(password)
          user.save(using=self._db)
  
          return user
  
      def create_superuser(self, email, username, first_name, last_name, password=None, **other_fields):
          &quot;&quot;&quot;
          Create and save a SuperUser with the given email and password.
          &quot;&quot;&quot;
  
          other_fields.setdefault('is_staff', True)
          other_fields.setdefault('is_superuser', True)
          other_fields.setdefault('is_admin', True)
  
          user = self.create_user(
              email=self.normalize_email(email),
              username=username,
              first_name=first_name,
              last_name=last_name,
              password=password,
              **other_fields
          )
  
          if other_fields.get('is_staff') is not True:
              raise ValueError('Superuser must be assigned to is_staff=True.')
          if other_fields.get('is_superuser') is not True:
              raise ValueError('Superuser must be assigned to is_superuser=True.')
  
          user.save(using=self._db)
  
          return user
  
  
  class NewUser(AbstractBaseUser, PermissionsMixin):
      # basic information
      email = models.EmailField(_('email address'), unique=True)
      username = models.CharField(max_length=150, unique=True)
      first_name = models.CharField(max_length=150, blank=True)
      last_name = models.CharField(max_length=150, blank=True)
  
      # Registration Date
      date_joined = models.DateTimeField(default=timezone.now)  ## todo: unterschied zu 'auto_now_add=True'
  
      # Permissions
      is_admin = models.BooleanField(default=False)
      is_superuser = models.BooleanField(default=False)
      is_staff = models.BooleanField(default=False)
      is_active = models.BooleanField(default=True)
  
      objects = CustomAccountManager()
  
      USERNAME_FIELD = 'email'
      REQUIRED_FIELDS = ['username', 'first_name', 'last_name']  # Note: USERNAME_FIELD not to be included in this list!
  
      def __str__(self):
          return self.email
  
      # For checking permissions. to keep it simple all admin have ALL permissons
      def has_perm(self, perm, obj=None):
          return self.is_admin
  
      # Does this user have permission to view this app? (ALWAYS YES FOR SIMPLICITY)
      def has_module_perms(self, app_label):
          return True
  
      @property
      def is_staff(self):
          &quot;Is the user a member of staff?&quot;
          # Simplest possible answer: All admins are staff
          return self.is_admin
  </code></pre>
  <h1>forms.py</h1>
  <pre><code>from django import forms
  from django.contrib import admin
  from django.core.exceptions import ValidationError
  
  # Import custom user model
  from django.contrib.auth import get_user_model
  custom_user_model = get_user_model()
  
  
  class CustomUserCreationForm(forms.ModelForm):
      &quot;&quot;&quot;A form for creating new users. Includes all the required
      fields, plus a repeated password.&quot;&quot;&quot;
  
      username = forms.CharField(label='Username', min_length=4, max_length=150)
      email = forms.EmailField(label='E-Mail')
      first_name = forms.CharField(label='First Name')
      last_name = forms.CharField(label='Last Name')
  
      password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
      password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
  
      class Meta:
          model = custom_user_model
          fields = ('username', 'first_name', 'last_name')
  
      def clean_password2(self):
          # Check that the two password entries match
          password1 = self.cleaned_data.get(&quot;password1&quot;)
          password2 = self.cleaned_data.get(&quot;password2&quot;)
          if password1 and password2 and password1 != password2:
              raise ValidationError(&quot;Passwords don't match&quot;)
          return password2
  
      def save(self, commit=True):
          # Save the provided password in hashed format
          user = super().save(commit=False)
          user.set_password(self.cleaned_data[&quot;password1&quot;])
          if commit:
              user.save()
  
          return user
  </code></pre>
  <h1>admin.py</h1>
  <pre><code>from django.contrib import admin
  from django.contrib.auth.admin import UserAdmin  # Helper Class for creating user admin pages
  
  from .forms import CustomUserCreationForm  #, CustomUserChangeForm
  from .models import NewUser, UserProfile
  
  
  class CustomUserAdmin(UserAdmin):
      add_form = CustomUserCreationForm
  
      model = NewUser
  
      list_display = ('email', 'username', 'date_joined', 'last_login', 'is_admin', 'is_staff')
      search_fields = ('email', 'username',)
      readonly_fields = ('date_joined', 'last_login',)
  
      filter_horizontal = ()
      list_filter = ()
      fieldsets = ()
  
  
  admin.site.register(custom_user_model, CustomUserAdmin)
  </code></pre>