Python 在 Django Admin 中更改密码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15456964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:11:20  来源:igfitidea点击:

Changing password in Django Admin

pythondjangodjango-admindjango-1.5

提问by Thomas

I recently created the admin.py based in the Django Project Document:

我最近在 Django 项目文档中创建了 admin.py:

https://docs.djangoproject.com/en/dev/topics/auth/customizing/#django.contrib.auth.models.AbstractBaseUser

https://docs.djangoproject.com/en/dev/topics/auth/customizing/#django.contrib.auth.models.AbstractBaseUser

But I really missed the functionality that allow the administrator the possibility to change the users passwords. How is possible to add this functionality? I just copied and pasted the code the is in the link above.

但我真的错过了允许管理员更改用户密码的功能。如何添加此功能?我只是复制并粘贴了上面链接中的代码。

from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField

from customauth.models import MyUser


class UserCreationForm(forms.ModelForm):
    """A form for creating new users. Includes all the required
    fields, plus a repeated password."""
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = MyUser
        fields = ('email', 'date_of_birth')

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user


class UserChangeForm(forms.ModelForm):
    """A form for updating users. Includes all the fields on
    the user, but replaces the password field with admin's
    password hash display field.
    """
    password = ReadOnlyPasswordHashField()

    class Meta:
        model = MyUser

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]


class MyUserAdmin(UserAdmin):
    # The forms to add and change user instances
    form = UserChangeForm
    add_form = UserCreationForm

    # 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', 'date_of_birth', 'is_admin')
    list_filter = ('is_admin',)
    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Personal info', {'fields': ('date_of_birth',)}),
        ('Permissions', {'fields': ('is_admin',)}),
        ('Important dates', {'fields': ('last_login',)}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'date_of_birth', 'password1', 'password2')}
        ),
    )
    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ()

# Now register the new UserAdmin...
admin.site.register(MyUser, MyUserAdmin)
# ... and, since we're not using Django's builtin permissions,
# unregister the Group model from admin.
admin.site.unregister(Group)

[UPDATE - Added Information]I changed the following information but I still seeing just the password (crypted) in a read-only field. How is possible to add a link to change the password?

[更新 - 添加信息]我更改了以下信息,但在只读字段中我仍然只看到密码(加密)。如何添加更改密码的链接?

fieldsets = (
    ('Permissions', {'fields': ('is_active', 'is_admin','password')}),
)
add_fieldsets = (
    (None, {
        'classes': ('wide',),
        'fields': ('email', 'password')}
    ),
)

采纳答案by kufudo

Put this in your UserChangeForm:

把它放在你的 UserChangeForm 中:

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 <a href=\"../password/\">this form</a>."))

回答by catherine

('Permissions', {'fields': ('is_active', 'is_superuser',)}),

回答by WhyNotHugo

I added this method to my UserAdminclass:

我将此方法添加到我的UserAdmin课程中:

def save_model(self, request, obj, form, change):
    # Override this to set the password to the value in the field if it's
    # changed.
    if obj.pk:
        orig_obj = models.User.objects.get(pk=obj.pk)
        if obj.password != orig_obj.password:
            obj.set_password(obj.password)
    else:
        obj.set_password(obj.password)
    obj.save()

You can the show the password field normally, but admins will only see the hashed password. If they alter it, the new value is then hashed and save.

您可以正常显示密码字段,但管理员只会看到散列密码。如果他们改变了它,新值就会被散列并保存。

This adds a single query to each time you save a user via the admin. It should generally not be an issue, since most systems don't have admins intensively editing users.

每次您通过管理员保存用户时,这都会添加一个查询。这通常不是问题,因为大多数系统没有管理员密集编辑用户。

回答by Yash Rastogi

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 <a href=\"../password/\">this form</a>."))

There is change in the href, for previous versions of django you can use

href 有变化,对于以前版本的 django,您可以使用

<a href=\"/password/\">this form</a>.

<a href=\"/password/\">this form</a>.

For django 1.9+ <a href=\"../password/\">this form</a>

对于 Django 1.9+ <a href=\"../password/\">this form</a>

回答by Max Peterson

For a django version independent solution you can reversethe url in the UserChangeForm.__init__with something like:

对于 django 版本独立解决方案,您可以使用以下内容中reverse的 url UserChangeForm.__init__

from django.core.urlresolvers import reverse

class UserChangeForm(forms.ModelForm):
    password = ReadOnlyPasswordHashField()
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['password'].help_text = (
            "Raw passwords are not stored, so there is no way to see "
            "this user's password, but you can <a href=\"%s\"> "
            "<strong>Change the Password</strong> using this form</a>."
        ) % reverse_lazy('admin:auth_user_password_change', args=[self.instance.id])

回答by Roberto Fernandez Diaz

You can also do like this, in this way you just have to write over the field password and once you will save it, it will create the hash for it :

您也可以这样做,通过这种方式,您只需覆盖字段密码,一旦保存,它将为其创建哈希:

class UserModelAdmin(admin.ModelAdmin):

    """
        User for overriding the normal user admin panel, and add the extra fields added to the user
        """


def save_model(self, request, obj, form, change):
    user_database = User.objects.get(pk=obj.pk)
    # Check firs the case in which the password is not encoded, then check in the case that the password is encode
    if not (check_password(form.data['password'], user_database.password) or user_database.password == form.data['password']):
        obj.password = make_password(obj.password)
    else:
        obj.password = user_database.password
    super().save_model(request, obj, form, change)