I wrote a custom admin class for Users in the Django Admin as follows:
class UserAdmin(admin.ModelAdmin):
model = User
list_display = ['email', 'first_name', 'last_name', 'last_login', 'date_joined', 'is_superuser', 'is_active']
list_filter = ['is_active', 'groups']
search_fields = ['email', 'first_name', 'last_name']
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
This breaks the 'change password' feature in the Django Admin. What do I have to add to my custom class to allow it to work again?
Thanks.
You need to inherit from django.contrib.auth.admin.UserAdmin, rather than
admin.ModelAdmin
Related
I am using UserCreationForm for registration of the user. Added one address filed as mandatory in the code. however whenever the user is registering on the html page the address input is present.In the admin panel for users the address is not present.
form.py
class RegistrationForm(UserCreationForm):
email=forms.EmailField(required=True)
address=forms.CharField(max_length=250,required=True)
class Meta:
model=User
fields=(
'username',
'first_name',
'last_name',
'email',
'address',
'password1',
'password2'
)
def save(self,commit=True):
user=super(RegistrationForm,self).save(commit=False)
user.first_name=self.cleaned_data['first_name']
user.last_name=self.cleaned_data['last_name']
user.email=self.cleaned_data['email']
if commit:
user.save()
return user
views.py
def register(request):
print("inside views")
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
return redirect('./login.html')
else:
form = RegistrationForm()
args = {'form': form}
return render(request,'./reg_form.html',args)
else:
form = RegistrationForm()
args = {'form': form}
return render(request,'./reg_form.html',args)
In the user model all the fields are seen in the admin page,just address is not present. However while registering the user, address input is accepted.
I think you need to add this code in your models.py this field you input is required, they are added by default.
Email & Password & last_name & first_name are required by default.
REQUIRED_FIELDS = ['Address', 'SomethingElse']
and then in your admin.py
admin.py
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from .forms import UserAdminCreationForm, UserAdminChangeForm
from .models import User
name of your class and your Object you want to add in admin page.
class UserAdmin(BaseUserAdmin):
# The forms to add and change user instances
form = UserAdminChangeForm
add_form = UserAdminCreationForm
# The fields to be used in displaying the User model.
# These override the definitions on the base UserAdmin
# that reference specific fields on auth.User.
list_display = ('email', 'admin', 'first_name', 'address')
list_filter = ('admin', 'staff', 'active')
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal info', {'fields': ('first_name', 'address')}),
('Permissions', {'fields': ('admin', 'staff', 'active')}),
)
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2', 'first_name', 'address', 'active', 'staff', 'admin')}
),
)
search_fields = ('email')
ordering = ('email',)
filter_horizontal = ()
admin.site.register(User, UserAdmin)
# Remove Group Model from admin. We're not using it.
admin.site.unregister(Group)
finally, you can check how I add address field into my project
by this link in Viva-ecommerce-models.py and Follow the Class Address
I created a custom user model with country in it:
models.py
class CustomUser(AbstractUser):
country = models.CharField(max_length=50, default="None")
Then added custom forms with form field country which is a ChoiceField and shows all the countries:
forms.py
class CustomUserCreationForm(UserCreationForm):
country = forms.ChoiceField(choices=sorted(COUNTRIES.items()), label="Country")
class Meta(UserCreationForm):
model = CustomUser
fields = '__all__'
class CustomUserChangeForm(UserChangeForm):
country = forms.ChoiceField(choices=sorted(COUNTRIES.items()), label="Country")
class Meta(UserChangeForm):
model = CustomUser
fields = '__all__'
Then I registered it in the admin with:
admin.py
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = CustomUser
list_display = ['email', 'username', 'is_staff',]
admin.site.register(CustomUser, CustomUserAdmin)
It registered and everything is working fine, I am able to save the model with Django shell and programmatically, but I am not able to display it in the admin console. When I try to try to create a new user from the admin, I just see three fields - username, password and password confirmation.
Do I have to extend the admin template for this new field to show up?
To do this you will have to add_fieldsets under CustomUserAdmin in admin.py:
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = CustomUser
list_display = ['email', 'username', 'is_staff',]
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'password1', 'password2', 'country'),
}),
)
admin.site.register(CustomUser, CustomUserAdmin)
In Django 4.1+, the add_form option on a ModelAdmin has been removed. You should instead use the get_form() argument, like follows:
···python
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
def get_form(self, request, obj=None, change=False, **kwargs):
if not change and not obj:
self.form = self.add_form
return super().get_form(request, obj, **kwargs)
···
I'm a django beginner and i want to add a booleanfield to AbstractUser, but it's not showing the booleanfield in the admin.
models.py
class CustomUser(AbstractUser):
selected = models.BooleanField(default=False)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['selected',]
def __str__(self):
return self.username
admin.py
class MyUserChangeForm(UserChangeForm):
class Meta(UserChangeForm.Meta):
model = CustomUser
class UserAdmin(BaseUserAdmin):
form = MyUserChangeForm
list_display = ('username', 'first_name', 'last_name', 'email', 'is_staff', 'selected')
admin.site.register(CustomUser, UserAdmin)
settings.py
AUTH_USER_MODEL = 'football_app.CustomUser'
in admin.py file change
class UserAdmin(BaseUserAdmin): to class UserAdmin(CustomUser):
EDIT: update your class like this
class UserAdmin(admin.ModelAdmin):
list_display = ('username', 'first_name', 'last_name', 'email', 'is_staff', 'selected')
class Meta:
model = CustomUser
You need to unregister current User admin first.
admin.site.unregister(User)
admin.site.register(CustomUser, UserAdmin)
After looking for the best way to extend user, I followed the way described here (https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model). Now I am looking for a way to let the user edit some of their fields from User (eg. first_name, last_name and email) and from the new class extended. It would be nice if this could be done on the same screen, but I am not sure if this is possible (I don't want to let the permissions editable for non superuser).
So, I have first tried this code in admin, but it not works:
#admin.py
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
class MyUserAdmin(UserAdmin):
def get_fieldsets(self, request, obj=None):
if request.user.is_superuser:
fieldsets = super(MyUserAdmin, self).get_fieldsets(request, obj)
else:
fieldsets = (
(None, {
'fields': ('username', 'first_name', 'last_name', 'email', 'password', 'last_login', 'date_joined',)
}),)
return fieldsets
# If not superuser, do not show some fields
def get_readonly_fields(self, request, obj=None):
ro_fields = super(MyUserAdmin, self).get_readonly_fields(request, obj)
if not request.user.is_superuser:
ro_fields = list(ro_fields) + ['username', 'last_login', 'date_joined',]
return ro_fields
admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)
Here is a piece of my model:
class Investigator(models.Model):
user = models.OneToOneField(User, verbose_name=_('User'))
force_password_change = models.BooleanField(_('Force password change'), default=True)
...
I got no error, but the changes are not saved. What I have to do to let the users edit some specific fields?
You need set up permission for the user to edit User model
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)