You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django自定义UserAdmin修改用户时如何隐藏哈希密码?

解决Django Admin修改用户时显示哈希密码的问题

嘿,我来帮你搞定这个问题!你遇到的情况很常见——自定义UserAdmin后,编辑用户时密码框会显示哈希后的密码,既不美观也不安全。下面给你几个实用的解决方案,还会顺便修正你代码里的一个小坑哦。

方案一:修改时隐藏密码字段,仅在添加时显示

这个方法最简单直接,我们在UserAdmin中重写get_fieldsets方法,区分添加和修改场景:

class UserAdminForm(forms.ModelForm):
    middle_name = forms.CharField(label='Отчество', empty_value='', required=False)
    class Meta:
        labels = {
            'last_name': 'Фамилия',
            'first_name': 'Имя',
            'password': 'Пароль',
        }

class UserAdmin(admin.ModelAdmin):
    form = UserAdminForm
    # 定义添加用户时的字段集合
    fields = ['username', 'password', 'last_name', 'first_name', 'middle_name', 'groups']
    list_display = ['username', 'last_name', 'first_name', 'url_get_money_from_user']

    def get_fieldsets(self, request, obj=None):
        # obj不为空说明是修改用户操作
        if obj:
            # 移除password字段,只保留其他必要字段
            return (
                (None, {'fields': ['username', 'last_name', 'first_name', 'middle_name', 'groups']}),
            )
        # obj为空是添加用户,保留原字段配置
        return super().get_fieldsets(request, obj)

    def url_get_money_from_user(self, obj):
        return format_html('<a href="/admin/fbp_common/person/{}/change/">{}</a>', obj.person.id, 'Списать средства')
    url_get_money_from_user.allow_tags = True
    url_get_money_from_user.short_description = 'Ссылка для списания денежных средств'

    # 修正密码保存逻辑!避免重复哈希导致密码失效
    def save_model(self, request, obj, form, change):
        obj.is_staff = True
        # 只有当用户输入了新密码时才更新
        password = form.cleaned_data.get('password')
        if password:
            obj.set_password(password)
        obj.save()

方案二:修改时显示友好的密码提示(更人性化)

如果想让用户明确知道密码是加密存储的,而不是直接隐藏字段,可以添加一个只读的提示字段:

class UserAdmin(admin.ModelAdmin):
    form = UserAdminForm
    fields = ['username', 'password', 'last_name', 'first_name', 'middle_name', 'groups']
    list_display = ['username', 'last_name', 'first_name', 'url_get_money_from_user']
    # 添加只读提示字段
    readonly_fields = ['password_status']

    def get_fieldsets(self, request, obj=None):
        if obj:
            return (
                (None, {'fields': ['username', 'last_name', 'first_name', 'middle_name', 'groups']}),
                ('Пароль信息', {'fields': ['password_status']}),
            )
        return super().get_fieldsets(request, obj)

    # 自定义只读字段的提示内容
    def password_status(self, obj):
        return 'Пароль хранится в зашифрованном виде.如需修改密码,请使用专门的密码修改功能或重新创建用户。'
    password_status.short_description = '状态说明'

    # 其他方法和修正后的save_model同上...

关键提醒:修复密码重复哈希的隐患

你原来的save_model方法直接使用form.data['password'],如果用户编辑时没有修改密码,这个值会是已经哈希过的字符串,再次调用set_password会把它二次哈希,导致用户原密码失效!所以一定要改成用form.cleaned_data.get('password'),只在密码有新输入时才更新。

这样修改后,添加用户时正常显示密码输入框,修改时要么隐藏密码字段,要么显示友好提示,同时彻底避免了密码失效的问题。

内容的提问来源于stack exchange,提问作者Dmitry Rusanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 13:58:10