3

I want to make the email field required in the user admin add and change pages. I read this post: Django User model email field: how to make it mandatory and I did this:

class MyUserCreationForm(UserCreationForm):
    def __init__(self, *args, **kwargs):
        super(MyUserCreationForm, self).__init__(*args, **kwargs)
        # make user email field required
        self.fields['email'].required = True

class UserAdmin(BaseUserAdmin):
    form = MyUserCreationForm
    add_form = MyUserCreationForm
    add_fieldsets = ((None, {'fields': ('username', 'email',
'password1', 'password2'), 'classes': ('wide',)}),)

admin.site.unregister(User)
admin.site.register(User, UserAdmin)

This works fine in add user, but in change user I get the user's encrypted password shown in the password field, instead of what you normally see:

algorithm: pbkdf2_sha256 iterations: 24000 salt: ****** hash:
**************************************
Raw passwords are not stored, so there is no way to see this user's
password, but you can change the password using this form.

And when I try to save from the change screen it says "Please correct the errors below." even though there are no errors shown.

How can I fix these issues in the change form?

Community
  • 1
  • 1
Larry Martell
  • 3,526
  • 6
  • 40
  • 76
  • Maybe you also need `fieldsets` in addition to `add_fieldsets` ? – denvaar Jan 31 '17 at 21:39
  • Tried that and then the empty password fields were shown in the change form and if they were left empty the form was not accepted. I also tried removing the password fields and then they were not shown, but the form was still not accepted. How do you get what you normally see in password on the change form? – Larry Martell Jan 31 '17 at 21:45

1 Answers1

16

Have a look at the source code of the UserAdmin.

The UserAdmin uses a UserChangeForm as it's formproperty and a UserCreationForm as it's add_form property. But you have overridden both of them with a class derived from UserCreationForm which is okay for the create view but doesn't work for the update view .

from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.contrib.auth.models import User

class EmailRequiredMixin(object):
    def __init__(self, *args, **kwargs):
        super(EmailRequiredMixin, self).__init__(*args, **kwargs)
        # make user email field required
        self.fields['email'].required = True


class MyUserCreationForm(EmailRequiredMixin, UserCreationForm):
    pass


class MyUserChangeForm(EmailRequiredMixin, UserChangeForm):
    pass


class EmailRequiredUserAdmin(UserAdmin):
    form = MyUserChangeForm
    add_form = MyUserCreationForm
    add_fieldsets = ((None, {
        'fields': ('username', 'email', 'password1', 'password2'), 
        'classes': ('wide',)
    }),)

admin.site.unregister(User)
admin.site.register(User, EmailRequiredUserAdmin)

This should do the trick.

trixn
  • 15,761
  • 2
  • 38
  • 55