I'm trying to create a cutom user in my Django with custom fields required like first_name, last_name, date_of_birth, gender, email, etc. So for this I overrided AbstractBaseUser
for my custom user, UserCreationForm
for creating new user and UserChangeForm
changing user's field values.
Models.py
class AppUserManager(BaseUserManager):
"""
Manager for class AppUser
"""
def _create_user(self, username, password, first_name, last_name,
date_of_birth, email, gender, is_staff, is_superuser,
**extra_fields):
"""
Creates and saves a User with the given username, email and password.
"""
now = timezone.now()
if not username:
raise ValueError('The given username must be set')
email = self.normalize_email(email)
user = self.model(username=username,
first_name=first_name, last_name=last_name,
date_of_birth=date_of_birth, email=email, gender=gender,
is_staff=is_staff, is_active=True,
is_superuser=is_superuser, last_login=now,
date_joined=now, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, username, password, first_name, last_name, date_of_birth, email, gender, **extra_fields):
return self._create_user(username, password, first_name, last_name,
date_of_birth, email, gender, False, False,
**extra_fields)
def create_superuser(self, username, password, first_name, last_name, date_of_birth, email, gender, **extra_fields):
return self._create_user(username, password, first_name, last_name,
date_of_birth, email, gender, True, True,
**extra_fields)
class AppUser(AbstractBaseUser, PermissionsMixin):
"""
User for Application
"""
username = models.CharField(verbose_name='username', max_length=30, unique=True,
help_text='Required. 30 characters or fewer. Letters, digits and '
'@/./+/-/_ only.',
validators=[
validators.RegexValidator(r'^[\w.@+-]+$', 'Enter a valid username.', 'invalid')
])
first_name = models.CharField(verbose_name='first name', max_length=30)
last_name = models.CharField(verbose_name='last name', max_length=30)
date_of_birth = models.DateField(verbose_name='birth date')
email = models.EmailField(verbose_name='email address', unique=True)
GENDER_CHOICES = (
('m', 'Male'),
('f', 'Female'),
)
gender = models.CharField(verbose_name='gender', max_length=1, choices=GENDER_CHOICES)
is_staff = models.BooleanField(verbose_name='staff status', default=False,
help_text='Designates whether the user can log into this admin '
'site.')
is_active = models.BooleanField(verbose_name='active status', default=True,
help_text='Designates whether this user should be treated as '
'active. Un select this instead of deleting accounts.')
date_joined = models.DateTimeField(verbose_name='date joined', default=timezone.now)
objects = AppUserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['first_name', 'last_name', 'date_of_birth', 'email', 'gender']
class Meta:
verbose_name = 'user'
verbose_name_plural = 'users'
db_table = 'app_users'
def get_full_name(self):
"""
Returns the first_name plus the last_name, with a space in between.
"""
full_name = '%s %s' % (self.first_name, self.last_name)
return full_name.strip()
def get_short_name(self):
"""Returns the short name for the user."""
return self.first_name
def email_user(self, subject, message, from_email=None, **kwargs):
"""
Sends an email to this User.
"""
send_mail(subject, message, from_email, [self.email], **kwargs)
admin.py
class CustomUserCreationForm(UserCreationForm):
"""
A form for creating new users. Includes all the required fields, plus a repeated password.
"""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password Confirmation', widget=forms.PasswordInput)
first_name = forms.CharField(label='First Name') # Custom Required Field. and other fields should go same way
class Meta(UserCreationForm.Meta):
model = AppUser
fields = ('username', 'first_name', 'last_name', 'date_of_birth', 'email', 'gender')
def clean_username(self):
username = self.cleaned_data["username"]
try:
AppUser.objects.get(username=username)
except AppUser.DoesNotExist:
return username
raise forms.ValidationError(self.error_messages['duplicate_username'])
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords do not match.")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super(UserCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class CustomUserChangeForm(UserChangeForm):
password = ReadOnlyPasswordHashField(label="password",
help_text="""Raw passwords are not stored, so there is no way to see this
user's password, but you can change the password using <a href=\"password/\">
this form</a>.""")
class Meta(UserChangeForm.Meta):
model = AppUser
fields = (
'username', 'first_name', 'last_name', 'date_of_birth', 'email', 'gender',
'password', 'is_active', 'is_staff', 'is_superuser', 'user_permissions'
)
def clean_password(self):
# Regardless of what the user provides, return the initial value.
# This is done here, rather than on the field, because the
# field does not have access to the initial value
return self.initial["password"]
class AppUserAdmin(UserAdmin):
"""
"""
form = CustomUserChangeForm
add_form = CustomUserCreationForm
list_display = ('username', 'first_name', 'last_name', 'email',)
list_filter = ('is_superuser',)
fieldsets = (
(None, {'fields': (
'username', 'first_name', 'last_name', 'date_of_birth', 'email', 'gender',
)}),
('Permissions', {'fields': (
'is_active', 'is_superuser', 'is_staff',
)}),
)
search_fields = ('username', 'email', 'first_name', 'last_name',)
ordering = ('username', 'email',)
admin.site.register(AppUser, AppUserAdmin)
I created a superuser from command line. But User add form only shows: Username, Password and Password Confirmation fields.
So how can I get fields in create user form having required fields displayed?
After submitting this gives me error:
Exception Type: IntegrityError at /admin/users/appuser/add/
Exception Value: Column 'date_of_birth' cannot be null
That's the correct form for adding a user. As the help text on top of the form states, the username and password are set first, then you will see the rest of the fields. If you edit an existing user you will also see everything.
in your AppUserAdmin add
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'first_name', 'last_name', 'gender', .........
'password1', 'password2')}
),
)
Of course add all of your required fields in the dots place. add_fieldsets is responsible for visible fields on django admin user creation site
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.