Django admin site user password change - django

Django admin site used to have a form to change the password for a user that wasn't the logged in user. You would look at the user's update page, and by the password field, there was a change password link. You would click it, and it would take you to a different page for changing the password. I used to take advantage of that page to allow changing of a user's password, without having to open the admin. In Django 4, it seems to now be missing. In fact, I can't figure out how one would change a user's password other than their own, without writing my own view.
I have 2 questions:
Is there a way in the admin site now to change a different user's password?
If this view is gone, what is now the best way for a superuser to have a view that can change passwords for a user?
Edit:
This is what I see. There is no link to change the password where there used to be.

Are you sure you have checked it right? When you select an user it appears by default in the upper part, just after some semi-blinded parameters of the password.

The problem was when I am using AbstractBaseUser, and the admin site registration I was using admin.ModelAdmin instead of UserAdmin.
from django.contrib.auth import get_user_model
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
class EmployeeAdmin(UserAdmin):
ordering = ['email', ]
list_display = ['email', ]
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Info', {'fields': ('first_name', 'last_name', 'phone',)}),
('Address', {'fields': ('address', 'city', 'state', 'zip_code')}),
('Schedule', {'fields': ('time_off',)}),
('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser',
'groups', 'user_permissions')}),
('Important dates', {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
("User Details", {'fields': ('email', 'password1', 'password2')}),
("Permission", {'fields': ('is_active', 'is_staff', 'is_admin')}),
)
admin.site.register(get_user_model(), EmployeeAdmin)

Related

User password is not hashed when creating through Django admin panel

I have inherited the user class to make custom authentication. I do not get password hashing this way. It just stores as plain text in MySQL database. I have created staff through admin panel and unable to login as staff. Furthermore I have also created auth API endpoints using DRF and Djoser and am unable to login with the user profiles created through Django admin panel.
Here is my code.
models.py
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
admin.py
from .models import User
class UserAdmin(admin.ModelAdmin):
pass
admin.site.register(User, UserAdmin)
I have seen old replies in Stack Overflow suggesting changing the parent class to django.contrib.auth.admin.UserAdmin . When I try this the add user template form only has 3 fields. Username, Password and Password Confirmation.
admin.py
from django.contrib.auth.admin import UserAdmin as DefaultUserAdmin
from .models import User
class UserAdmin(DefaultUserAdmin):
pass
admin.site.register(User, UserAdmin)
How do I solve this problem.
I wrote a custom UserAdmin as well so i guess i can help you a little bit with that
try this one:
#admin.register(User)
class UserAdmin(UserAdmin):
"""Define admin model for custom User model with no email field."""
fieldsets = (
(None, {'fields': ('email', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name')}),
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2'),
}),
)
list_display = ('email', 'is_staff')
search_fields = ('email',)
ordering = ('email',)
And i also think that there`s problems in your models.py bcs you dont have userManager
UserManager uses when you`re creating user so i guess problem in that

Django: Restrict staff user to give more permissions to a group than his own

I've created a Django app having multiple types of users.
There is one Superuser who can access all the data and do the modification stuff. There are few staff users, who have limited access, mostly of view but can add new users and groups.
Below is the group permission for the staff user. He can add a new group but cannot change, view or delete existing.
But when I try to create a new group, he can assign all the possible permissions to the new group, even though he doesn't have those permissions himself. Below is the view he can see when creating a new group.
How can I only show those permissions which the staff user himself have and not to show complete options?
I am using Django 2.1
This worked for me:
Create groups with various permissions
Prevent add or delete groups
#other imports
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
class UserAdmin(BaseUserAdmin):
list_display = ('username', 'email', 'is_staff')
list_filter = ('is_staff',)
#this displays after initial user creation for additional information
fieldsets = (
(None, {'fields': ('username', 'email', 'password')}),
('Personal info', {'fields': ('first_name',)}),
('Permissions', {'fields': ('is_staff', 'is_active', 'groups')}),
)
# 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': ('username', 'email', 'password1', 'password2')}
),
)
search_fields = ('username',)
ordering = ('username',)
#unregister the default user admin
admin.site.unregister(User)
# Now register the new UserAdmin...
admin.site.register(User, UserAdmin)
This way, the user can not get additional permissions

Django allow edit user password in admin site

I know similar questions has been asked before, but I can't get this to work.
I have overriden the user admin template so i can show only specific fields of the user. This is working.
But I can't edit the user password becouse it appears hashed. I want to ad a link as it was before.
I took a look at the solutions but they didnt worked. My code is as following:
class UserAdmin(admin.ModelAdmin):
fieldsets = (
(None, {'fields': ('username', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
(_('Permissions'), {'fields': ('is_active', 'is_superuser')}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
list_display = ('username', 'email', 'first_name', 'last_name')
list_filter = ('is_active', 'groups')
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 this form."))
admin.site.unregister(User)
admin.site.register(User,UserAdmin)
All of this works fine but the password is showing as a simple field and the text doesnt appears...
Thank you!!
You will never "edit" the password because it is not saved "in clear" but encrypted at first.
You could add a link to a different view using AdminPasswordChangeForm.
Documentation here
That's the solution:
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 this form."))
this form will link to it. The problem is that you've miss-placed this. It should be under the UserChangeForm. For example (depending on the User table you're using):
class AdminUserChangeForm(forms.ModelForm):
password = ReadOnlyPasswordHashField(
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 this form."
)
class Meta:
model = User
fields = (
'email', 'first_name', 'last_name',
)
def clean_password(self):
...
return self.initial["password"]
class UserAdmin(BaseUserAdmin):
...
fieldsets = (
('Login', {
'fields': [
'email',
'password',
]
}),
...
)
...
form = AdminUserChangeForm
add_form = AdminUserCreationForm

Username still required in custom user model

I am trying to use the new functionality in Django 1.5 to make use of an email address as the username.
Everything is working fine, bar the admin site to update users, which I have had to fiddle with to make passwords not appear raw (and use the password change form etc.) using this code:-
class PlayerChangeForm(UserChangeForm):
class Meta(UserChangeForm.Meta):
model = Player
class PlayerCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = Player
class PlayerAdmin(auth.admin.UserAdmin):
form = PlayerChangeForm
add_form = PlayerCreationForm
ordering = ['first_name', 'last_name']
list_display = ('primkey', 'email', 'mobile')
list_editable = ('email', 'mobile')
list_filter = ()
fieldsets = ((None, {'fields': ('username', 'first_name', 'last_name', 'email', 'password', 'mobile')}),
('Permissions', {'fields': ('is_active', 'is_admin')}),
('Important dates', {'fields': ('last_login', )}),
)
add_fieldsets = ((None, {
'classes': ('wide',),
'fields': ('username', 'first_name', 'last_name', 'email', 'password1', 'password2')}
),
)
filter_horizontal = ()
def primkey(self, obj):
return ("%s" % (obj.get_full_name()))
primkey.short_description = 'Player'
This makes the admin page look fine but when I actually try and update a Player, it tells me there is an error on the form but doesn't indicate where.
After a bit of messing around, it turns out that it wants the username field to be set (if I add that into the admin form, it says this field is required) but surely this isn't the case as I have set my USERNAME_FIELD to be 'email'?
If I set the field to something, I can then save any changes I've made to the other fields but it doesn't save my update to the username field. But really, I don't want to have to set the username at all - I'm using the email as the username.
Any ideas about this or is this a bug in Django?
The Django Documentation states that the forms must be rewritten:
UserCreationForm
Depends on the User model. Must be re-written for any custom user model.
UserChangeForm
Depends on the User model. Must be re-written for any custom user model.
There is a related ticket: https://code.djangoproject.com/ticket/19353 but the code still expect a username field to be present.

Changing Django prebuild form to add new user

I was given a task to add a field "location" to the django prebuilt user module
I found the location of the module itself and added the location field as well as the admin modules
eg:
class UserAdmin(admin.ModelAdmin):
add_form_template = 'admin/auth/user/add_form.html'
change_user_password_template = None
fieldsets = (
(None, {'fields': ('username', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name', 'email', 'location')}),
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', 'user_permissions')}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
(_('Groups'), {'fields': ('groups',)}),
)
I rebuilt the database hoping it would show up in the adding of new user form.
But It didn't seem to work. So I assume I forgot to change something else.
I was looking around in the html code for ages trying to find the location of where the actual "change user" form is called, but couldn't find it.
I would appreciate help from someone who dealt with the pre built django admin backend before.
Thank you!
It's not recommended to modify django's user model because it complicates things. Instead, you can add a user profile as documented here.
If you want the profile to show up in the admin side, you can attach the profile as an inline and force it by unregistering the user and then re-registering it. Here's how I do it:
from django.contrib.auth.models import User
from reversion.admin import VersionAdmin
from profiles.models import Profile
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
class ProfileInline(admin.StackedInline):
model = Profile
fk_name = 'user'
extra = 0
max_num = 1
fieldsets = [
('Company', {'fields': ['company', 'office']}),
('User Information', {'fields': ['role', 'gender', 'phone', 'mobile', 'fax', 'street', 'street2', 'city', 'state', 'zip']}),
('Site Information', {'fields': ['sites']}),
]
class NewUserAdmin(VersionAdmin):
inlines = [ProfileInline, ]
admin.site.unregister(User)
admin.site.register(User, NewUserAdmin)