So to use email as username I override the build-in User model like this (inspired by Django source code)
models.py
class User(AbstractUser):
username = None
email = models.EmailField(unique=True)
objects = UserManager()
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []
def __str__(self):
return self.email
admin.py
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
fieldsets = (
(None, {"fields": ("email", "password")}),
(("Personal info"), {"fields": ("first_name", "last_name")}),
(
("Permissions"),
{
"fields": (
"is_active",
"is_staff",
"is_superuser",
"groups",
"user_permissions",
),
},
),
(("Important dates"), {"fields": ("last_login", "date_joined")}),
)
add_fieldsets = (
(
None,
{
"classes": ("wide",),
"fields": ("email", "password1", "password2"),
},
),
)
list_display = ("email", "is_active", "is_staff", "is_superuser")
list_filter = ("is_active", "is_staff", "is_superuser")
search_fields = ("email",)
ordering = ("email",)
filter_horizontal = ("groups", "user_permissions",)
But this is how it looks like when I go to Admin site to change a user:

Password is visible and not hashed and no link to change password form.
Comparing to what it looks like on a default Django project:

Password is not visible and there's a link to change password form
So clearly I'm missing something but I can't figure out what it is.
It's likely that the Django Admin look problem has to do with inheritance. More precisely, change the class to inherit from UserAdmin.
from django.contrib.auth.admin import UserAdmin as DefaultUserAdmin
class UserAdmin(DefaultUserAdmin):
Doing this will make it look closer to the default Django project.
The problem of the password not being encrypted is likely because it's not encrypted in the database. OP has this question and that's not a problem of the Django Admin.
Notes:
I also use AbstractUser when wanting to remove username.
Since this current question doesn't have enough info to answer the problem of the pwd being hashed, I'll leave that to OP's other question.
You are not able to see the password in hashed state because the password field is a CharField which renders it as normal text field. In Django's admin side there's a field called ReadOnlyPasswordHashField in django.contrib.auth.forms which renders the password field to be in hashed state with password change link.
Django's UserAdmin uses different form classes for user creation and updation.
form = UserChangeForm
add_form = UserCreationForm
change_password_form = AdminPasswordChangeForm
To edit user details UserAdmin uses form = UserChangeForm(source code) where the password field is set as ReadOnlyPasswordHashField(source code).
class UserChangeForm(forms.ModelForm):
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="{}">this form</a>.'
),
)
So, Just by inheriting from UserAdmin from django.contrib.auth.admin would make the password to be in hashed state with all the other essentials as seen in default admin site for users.
OR
you could simply import UserChangeForm from django.contrib.auth.forms and set form = UserChangeForm in custom UserAdmin
from django.contrib.auth.forms import UserChangeForm,AdminPasswordChangeForm
# code
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
# code
form = UserChangeForm
change_password_form = AdminPasswordChangeForm
# code
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With