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
Related
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)
I have made custom BaseUserManager to create user but I am getting error of "please correct the errors below" when I add user from django admin panel and I can't find what's going wrong.
Models.py:
class UserManager(BaseUserManager):
def create_user(self,email,password):
user = self.model(email=email)
user.set_password(password)
def create_superuser(self,email,password):
user = self.model(email=email)
user.set_password(password)
user.is_admin = True
user.is_superuser = True
user.is_staff=True
user.save(using=self._db)
class User(AbstractBaseUser,PermissionsMixin):
COMPANY='CO'
EMPLOYEE='EM'
STATUS_CHOICES=(
(COMPANY,'Company'),
(EMPLOYEE,'Employee'),
)
Status=models.CharField(max_length=2,
choices=STATUS_CHOICES,
default=EMPLOYEE)
user_image = models.CharField(max_length=100)
is_admin=models.BooleanField()
email=models.EmailField(unique=True)
is_staff=models.BooleanField(default=False)
object = UserManager()
USERNAME_FIELD='email'
REQUIRED_FIELDS = []
objects=models.Manager()
def get_short_name(self):
return self.email
Admin.py files:
class UserAdmin(UserAdmin):
list_display = ('email', 'is_admin')
list_filter = ('is_admin',)
fieldsets = (
(None, {'fields': ('email', 'password','Status','user_image','last_login')}),
('Permissions', {'fields': ('is_admin','is_staff','is_superuser','user_permissions','groups')}),
)
add_fieldsets= (
(None, {'fields': ('email', 'password','Status','user_image','last_login')}),
('Permissions', {'fields': ('is_admin','is_staff','is_superuser','user_permissions','groups')}),
)
search_fields = ('password',)
ordering = ('password',)
filter_horizontal = ()
admin.site.register(User,UserAdmin)
admin.site.register(Company)
admin.site.register(Employee)
admin.site.register(Job)
admin.site.register(AppliedJobs)
Can someone suggest what I am doing wrong? I always get the error when I add user from admin panel.I can't figure out as I am working first time on baseusermanager.
I can suggest how to try and find the problem. Usually, your UserAdmin will refer to forms, see below:
class UserAdmin(UserAdmin):
add_form = SignUpForm
form = CustomUserChangeForm
You can find out what is causing the errors by using logging. Add the following Mixin to your SignUpForm and CustomUserChangeForm:
import logging
logger = logging.getLogger(__name__)
# see https://stackoverflow.com/questions/20833638/how-to-log-all-django-form-validation-errors
class LoggingMixin(object):
def add_error(self, field, error):
if field:
logger.info('Form error on field %s: %s', field, error)
else:
logger.info('Form error: %s', error)
super().add_error(field, error)
# e.g.
class SignUpForm(LoggingMixin, UserCreationForm):
....
Now, either sign in or change a user and check the logs to find out what is causing the "Please correct the errors below.".
Had the same problem and answer is pretty simple.
The problem is in your add_fieldsets. Django use his own pattern for adding new users (you can check it in UserAdmin model in django.contrib.auth.admin.py file). You need to define fields for password1 and password2.
For your convenience I will paste it there:
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'password1', 'password2'),
}),
)
Here you have 2 options:
P.S. in any case you need to define username, password1 and password2 fields.
Use superclass field and add your custom:
add_fieldsets = UserAdmin.add_fieldsets + (
(None, {'fields': ('email', 'Status', 'user_image', 'last_login')}),
('Permissions', {'fields': ('is_admin', 'is_staff', 'is_superuser', 'user_permissions', 'groups')}),
)
Define by your own:
add_fieldsets = (
(None, {'fields': ('username', 'email', 'password1', 'password2', 'Status', 'user_image', 'last_login')}),
('Permissions', {'fields': ('is_admin', 'is_staff', 'is_superuser', 'user_permissions', 'groups')}),
)
I have two diffeent fieldsets depending on wether a user is in the 'leader' group or not. The fieldset show exactly what I want, except when I try to add a new user, from a user in the 'Leader' group, I now get a different user creation form.
I got how to do the different fieldsets from here, and I tried ensuring the form is indeed the right one by overriding the custom form as done here.
class UserCreateForm(UserCreationForm):
class Meta:
model = User
fields = ('username', 'password1', 'password2')
class UserProfileInline(admin.StackedInline):
model = UserProfile
can_delete = False
verbose_name_plural = 'UserProfile'
fk_name = 'scout_username'
class CustomUserAdmin(UserAdmin):
#ensuring it's the right form
add_form = UserCreateForm
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'password1', 'password2'),
}),
)
inlines = (UserProfileInline, )
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')}),
)
leader_fieldsets = (
((None), {'fields': ('username', 'password')}),
(('Personal'), {'fields': ('first_name', 'last_name')}),
)
#making it so leaders can only view the fields within leaders_fieldset
#removing this also removes the problem yet all the fields are shown regardless of the user's group
def get_fieldsets(self, request, obj=None):
if request.user.groups.filter(name='Leader').exists():
return self.leader_fieldsets
else:
return super(CustomUserAdmin, self).get_fieldsets(request, obj=obj)
#adding the userprofile stuff to the user change form
def get_inline_instances(self, request, obj=None):
if not obj:
return list()
return super(CustomUserAdmin, self).get_inline_instances(request, obj)
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)
If the user is not in the 'Leader' group I get the original user creation form.
User Creation Form if user is not in Leader Group
Else I get a form with the fields, username, password (which is not a password type as anything written in it is clear text) and then I get first name and last name.
User Creation Form if user is in Leader Group
Could someone please explain to me why this is happening and what I can do to fix it?
A little trick which worked for this particular case follows the fact that the url always had 'ADD' at the end.
Thus by checking if it was the user-add form currently on the page a function could return true or false.
def is_add_form(request):
path_info = request.META.get('PATH_INFO')
last_path = str(path_info.split('/')[-2])
if last_path == 'add':
return True
else:
return False
This worked with great success and I hope it helps others.
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.
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)