【问题标题】:Django admin change user passwordDjango 管理员更改用户密码
【发布时间】:2018-07-22 05:28:16
【问题描述】:

我是 Django 新手。我有以下代码:

型号:

class MyUser(AbstractUser):
    profile = models.OneToOneField(Profile, null=True, on_delete=models.PROTECT)

我的个人资料模型仅包含一些个人字段,例如全名、性别、出生日期等。

管理员:

class MyUserInline(admin.StackedInline):
    model = MyUser
    exclude = ('first_name', 'last_name', 'username', 'plan', 'password')
    fieldsets = (
        (_('Personal info'), {'fields': ('email',)}),
        (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser',
                                       'groups', 'user_permissions')}),
        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
    )


class MyUserChangeForm(UserChangeForm):
    class Meta(UserChangeForm.Meta):
        model = MyUser

    def clean_password(self):
        return ""

class ProfileAdmin(admin.ModelAdmin):
    inlines = (MyUserInline,)
    change_user_password_template = None
    form = MyUserChangeForm
    change_password_form = AdminPasswordChangeForm
    ordering = ('myuser__email',)

    def save_model(self, request, obj, form, change):
        obj.myuser.username = obj.myuser.email
        obj.save()

    list_display = ('full_name', 'myuser_email', 'myuser_is_staff', 'myuser_is_superuser', 'myuser_is_active')

    def user_change_password(self, request, id, form_url=''):
    if not self.has_change_permission(request):
        raise PermissionDenied
    user = self.get_object(request, unquote(id))
    if user is None:
        raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {
            'name': force_text(self.model._meta.verbose_name),
            'key': escape(id),
        })
    if request.method == 'POST':
        form = self.change_password_form(user, request.POST)
        if form.is_valid():
            form.save()
            # rest of method

    # other minor methods 

我无法更改用户密码。一开始修改密码页面根本打不开(Profile with ID "3/password" doesn't exist. Perhaps it was deleted?)

添加以下代码后它会打开,但在按下保存按钮后,我得到'Profile' object has no attribute 'set_password'

def get_urls(self):
    return [
               url(
                   r'^(.+)/password/$',
                   self.admin_site.admin_view(self.user_change_password),
                   name='auth_user_password_change',
               ),
           ] + super(ProfileAdmin, self).

添加以下行后,没有出现错误,点击保存按钮后应该是changed successfully,但它没有。

class Profile(models.Model):
.......

    def set_password(self, raw_password):
        self.myuser.password = make_password(raw_password)
        self.myuser._password = raw_password

【问题讨论】:

    标签: python django django-admin


    【解决方案1】:

    问题已解决:

    class MyAdminPasswordChangeForm(AdminPasswordChangeForm):
    
        def save(self, commit=True):
            """
            Saves the new password.
            """
            password = self.cleaned_data["password1"]
            self.user.myuser.set_password(password)
            if commit:
                self.user.myuser.save()
            return self.user.myuser
    

    class ProfileAdmin(UserAdmin):
        change_password_form = MyAdminPasswordChangeForm
    

    【讨论】:

      【解决方案2】:

      升级到 django 2.x 后我遇到了这个错误。我已经建立了自己的UserChangeForm,所以我只需要更新它的网址:

      class EmailUserChangeForm(forms.ModelForm):
          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>."))
      +        "using <a href=\"../password/\">this form</a>."))
      

      【讨论】:

        最近更新 更多