Adding required email field to django when creating users with admin - django

When creating/adding a user with Django admin; how can this be customized?
For example, currently, the username and password are prompted for. However, I'd like to customize this to also have other required fields, such as 'email'?
The Django tutorial isn't clear on admin user auth customization?

Place this in your models.py.
from django.contrib.auth.models import User
User._meta.get_field('email').blank = False
Run makemigrations.
Run migrate.
See the documentation

Example for adding email to form when creating a user. In project admin.py added the following:
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
class UserAdmin(UserAdmin):
fieldsets = (
(None, {'fields': ('username', 'password','email')}),
(_('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': ('username', 'password1', 'password2', 'email')}
),
)
form = UserChangeForm
add_form = UserCreationForm
try:
admin.site.unregister(User)
except NotRegistered:
pass
admin.site.register(User, UserAdmin)

This is how you can customize the user admin:
from django.contrib import admin
from django.contrib.auth import admin as upstream
# custom admin class for the User model, subclassing Django's one
class UserAdmin(upstream.UserAdmin):
add_form_template = ...
add_form = ...
add_fieldsets = ...
# unregister any existing admin for the User model and register mine
try:
admin.site.unregister(User)
except NotRegistered:
pass
admin.site.register(User, UserAdmin)
The parts I left with ... are the customizations you need to do to change the way the admin prompts for user creation.
Look for the original code in django/contrib/auth/admin.py and modify to taste.

Related

Problem adding user's email in Django admin

I created a custom model extending AbstractUser in order to authenticate users by email instad of by username (but not wanting to drop the username, because it will also be used).
This was the first thing I made before running the first migration, everything worked correctly except in the Django admin, when I create a new user, I want these fields to be filled
username
email
password
And the admin only ask me for the username and password. How could I add the email too? Here's my codes
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.base_user import BaseUserManager
from django.utils.translation import ugettext_lazy as _
class CustomUserManager(BaseUserManager):
"""
Custom user model manager where email is the unique identifier for
authentication instead of username.
"""
def create_user(self, email, password, **extra_fields):
"""
Create and save a User with the given email and password.
"""
if not email:
raise ValueError(_('The Email must be set'))
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **extra_fields):
"""
Create and save a SuperUser with the given email and password.
"""
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
if extra_fields.get('is_staff') is not True:
raise ValueError(_('Superuser must have is_staff=True.'))
if extra_fields.get('is_superuser') is not True:
raise ValueError(_('Superuser must have is_superuser=True.'))
return self.create_user(email, password, **extra_fields)
class User(AbstractUser):
email = models.EmailField(_('email address'), unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserManager()
def __str__(self):
return self.email
admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User as CustomUser
class CustomUserAdmin(UserAdmin):
model = CustomUser
list_display = ('email', 'is_staff', 'is_active',)
list_filter = ('eamil', 'is_staff', 'is_active',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Permissions', {'fields': ('is_staff', 'is_active')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2', 'is_staff', 'is_active')}
),
)
search_fields = ('email',)
ordering = ('email',)
admin.site.register(CustomUser, UserAdmin)
What I have to do? It seems that everything is correct, but the required email field is missing. Notice that this only happens when I use the Add User feature in the admin. When I create a superuser or when I login to the admin, everything is working as expected.
UPDATE:
Here's the content of my forms.py
from django.contrib.auth.forms import UserCreationForm
# the user model was customized it should be invoked
from django.contrib.auth import get_user_model
from django.contrib.auth import forms as auth_forms
from .models import User as CustomUser
class UserChangeForm(auth_forms.UserChangeForm):
class Meta(auth_forms.UserChangeForm.Meta):
model = CustomUser
class UserCreationForm(auth_forms.UserCreationForm):
class Meta(auth_forms.UserCreationForm.Meta):
model = CustomUser
fields = ("username", "email")
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
# the user model was customized it should be invoked
model = get_user_model()
fields = UserCreationForm.Meta.fields + ("email",)
And here the content (updated) of my admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User as CustomUser
from .forms import UserChangeForm, UserCreationForm
class CustomUserAdmin(UserAdmin):
model = CustomUser
list_display = ('email', 'username', 'is_staff', 'is_active',)
list_filter = ('eamil', 'username', 'is_staff', 'is_active',)
form = UserChangeForm
add_form = UserCreationForm
fieldsets = (
(None, {'fields': ('email', 'username', 'password')}),
('Permissions', {'fields': ('is_staff', 'is_active')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'username', 'password1', 'password2', 'is_staff', 'is_active')}
),
)
search_fields = ('email',)
ordering = ('email',)
admin.site.register(CustomUser, UserAdmin)
But I still have the same problem, I still can't add an email field in /admin/users/user/add/
The UserAdmin class has the attributes form and add_form which point to form classes to be used to edit and create the user respectively. You need to override these form classes and also set these attributes yourself as these two forms are created for the default user model.
Firstly define these custom forms:
from django.contrib.auth import forms as auth_forms
from .models import User as CustomUser
class UserChangeForm(auth_forms.UserChangeForm):
class Meta(auth_forms.UserChangeForm.Meta):
model = CustomUser
class UserCreationForm(auth_forms.UserCreationForm):
class Meta(auth_forms.UserCreationForm.Meta):
model = CustomUser
fields = ("username", "email")
Next set these in your CustomUserAdmin:
from .forms import UserChangeForm, UserCreationForm
class CustomUserAdmin(UserAdmin):
# Your other attributes here
form = UserChangeForm
add_form = UserCreationForm
In your code, I see
admin.site.register(CustomUser, UserAdmin)
but you have to register through your CustomUserAdmin.
Change your admin.py code to
admin.site.register(CustomUser, CustomUserAdmin)

How to remove user_permissions from django admin panel

let me know how to remove the user_permission field from user and groups in a model as shown in below pic
You can remove a field from the default user admin by overriding the UserAdmin Class [source]
# admin.py
from django.contrib.auth.admin import UserAdmin
class CustomUserAdmin(UserAdmin):
# ...
fieldsets = (
(None, {'fields': ('username', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
(_('Permissions'), {
'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions'),
}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
admin.site.register(UserModel, CustomUserAdmin)
See detailed example
Use this to remove user_permission
exclude = ('user_permissions',)
Completing #SATYA's answer, you can do the following:
# admin.py
from django.contrib import admin
from django.contrib.auth.models import User
class CustomUserAdmin(admin.ModelAdmin):
exclude = ('user_permissions',)
admin.site.register(User, CustomUserAdmin)
You could also extend Django's UserAdmin (from django.contrib.auth.admin), but this could mess up if you use a custom User model.

Create custom user form

On Django Admin, the default 'create user' form has 3 fields: username, password and confirm password.
I need to customize the create user form. I want to add the firstname and lastname fields, and autofill the username field with firstname.lastname.
How can I do this?
Something like this should work:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class UserCreateForm(UserCreationForm):
class Meta:
model = User
fields = ('username', 'first_name' , 'last_name', )
class UserAdmin(UserAdmin):
add_form = UserCreateForm
prepopulated_fields = {'username': ('first_name' , 'last_name', )}
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('first_name', 'last_name', 'username', 'password1', 'password2', ),
}),
)
# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
Only add_fieldsets is enough. No need to provide the add_form.
this would be the full code for admin.py, you can read about it in the Django docs here
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
class UserAdmin(UserAdmin):
add_fieldsets = (
(
None,
{
'classes': ('wide',),
'fields': ('username', 'email', 'password1', 'password2'),
},
),
)
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
As a side note: 'classes':('wide',), sets the style of the field to open or "not collapsed", you can read more about the options for that here

How to add fields in extended UserAdmin

I'm trying to create custom user models with their own admins (add and change forms). I'd like to have exactly the same as the original User admin with just the additional fields in the add and change forms.
Anybody could help?
models.py
from django.contrib.auth.models import User
class MyUser1(User):
#add more fields specific to MyUser1
class MyUser2(User):
#add more fields specific to MyUser2
admin.py
from django.contrib.auth.admin import UserAdmin
class MyUser1Admin(UserAdmin):
# how can I add the "fields specific to MyUser1" both in the add
# and the change forms?
admin.site.register(MyUser1, MyUser1Admin)
# same for MyUser2
I had to extend the UserCreationForm and UserChangeForm:
admin.py
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.contrib.auth.admin import UserAdmin
from django.contrib import admin
from django import forms
class MyUser1CreationForm(UserCreationForm):
myuser1_field = forms.CharField()
class Meta:
model = User
fields = ("username", "myuser1_field", "password1", "password2")
class MyUser1ChangeForm(UserChangeForm):
myuser1_field = forms.CharField()
class Meta:
model = User
class MyUser1Admin(UserAdmin):
form = MyUser1ChangeForm
add_form = MyUser1CreationForm
fieldsets = (
(None, {'fields': ('username', 'password')}),
(_('Personal info'), {'fields': ('myuser1_field', 'first_name', 'last_name', 'email')}),
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser',
'groups', 'user_permissions')}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'myuser1_field', 'password1', 'password2')}
),
)
admin.site.register(MyUser1, MyUser1Admin)
from django.contrib.auth.forms import UserChangeForm
class MyUser1AdminForm(UserChangeForm):
class Meta:
model = MyUser1

Changing User ModelAdmin for Django admin

How do you override the admin model for Users? I thought this would work but it doesn't?
class UserAdmin(admin.ModelAdmin):
list_display = ('email', 'first_name', 'last_name')
list_filter = ('is_staff', 'is_superuser')
admin.site.register(User, UserAdmin)
I'm not looking to override the template, just change the displayed fields & ordering.
Solutions please?
You have to unregister User first:
class UserAdmin(admin.ModelAdmin):
list_display = ('email', 'first_name', 'last_name')
list_filter = ('is_staff', 'is_superuser')
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
Maybe this question is also interesting for you: Customizing an Admin form in Django while also using autodiscover
Update tested with Django 3+
So you don't lose data like password encryption and the form itself, perform the import below
from django.contrib.auth.admin import UserAdmin
Define an AdminCustom class as the example and customize with the options you want, overriding the default.
class UserAdminCustom(UserAdmin):
list_display = ('email', 'first_name', 'last_name', 'is_staff', 'is_superuser')
list_filter = ('is_staff', 'is_superuser')
search_fields = ('username', )
And in the end, follow the example mentioned
admin.site.unregister(User)
admin.site.register(User, UserAdminCustom)
As pointed by #haifeng-zhang in the comments, it is useful to extend the default UserAdmin instead.
The official documentation about this can be found here:
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User
# Define a new User admin
class UserAdmin(BaseUserAdmin):
list_display = ('email', 'first_name', 'last_name')
list_filter = ('is_staff', 'is_superuser')
# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)