Search code examples
pythondjangodjango-allauth

Prevent Superuser from deleting/removing/editing User Email in Django Admin


I am using django-allauth for User signup and login purposes. Users can login using both username and email.

# settings.py

# Custom User Model
AUTH_USER_MODEL = 'users.User'

# ask for either username or email during login
ACCOUNT_AUTHENTICATION_METHOD = 'username_email'
# Set Email field as required during signup
ACCOUNT_EMAIL_REQUIRED = True
# Set email versification necessary before creating account
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
# Don't ask for username while signing up.
# Users can later edit/change username in their profile.
# If username is not set, use email to log in.
ACCOUNT_USERNAME_REQUIRED = False
# Login the user after email-confirmations
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True

I have a users app which implements a custom User Model as shown.

# users/models.py

class User(AbstractUser):

    name = models.CharField(blank=True, max_length=255)

    def __str__(self):
        return self.username

    def get_absolute_url(self):
        return reverse('users:detail', kwargs={'username': self.username})

Using this setup, I am able to make user login via both email and username. However, the problem being the fact that Superuser is able to edit/remove 'email' in Django Admin. I don't want such behaviours. (An attempt to remove username however gives an "field required" error.)

My question now is, How to prevent the Admin from editing the user information. i.e make 'username' and 'email' read-only fields.


Solution

  • You can make a custom Model admin for user and add readonly_fields = ('email',)

    @admin.register(User)
    class UserAdmin(DjangoUserAdmin):
    
    
    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        (_('Personal info'), {'fields': ('first_name', 'last_name')}),
        (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser','role',
                                       'groups', 'user_permissions')}),
        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'password1', 'password2'),
        }),
    )
    list_display = ('email', 'first_name', 'last_name', 'is_staff')
    search_fields = ('email', 'first_name', 'last_name')
    ordering = ('email',)
    readonly_fields = ('email',)