我一直在尝试让默认的 Django 身份验证系统与自定义用户一起使用。我能够创建用户类型、登录和注销。但是,当涉及到更改密码时,我会注销,然后密码就不会更改。我还尝试查看通过电子邮件重置密码是否会改变任何内容,但我仍然无法更改密码。我的应用程序名称是帐户。
这是我的自定义用户模型,我尝试添加 set_password 方法以确保它可以更改密码。我仅包含用户管理器以提高可读性:
class UserManager(BaseUserManager):
def _create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError("The given email must be set")
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password=None, **extra_fields):
extra_fields.setdefault("is_staff", False)
extra_fields.setdefault("is_superuser", False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password=None, **extra_fields):
extra_fields.setdefault("is_staff", True)
extra_fields.setdefault("is_superuser", True)
if extra_fields.get("is_staff") is not True:
raise ValueError("Superuser must have is_staff=True.")
if extra_fields.get("is_superuser") is not True:
raise ValueError("Superuser must have is_superuser=True.")
return self._create_user(email, password, **extra_fields)
class CustomUser(AbstractUser):
username = None
email = models.EmailField(_("email address"), unique=True)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []
objects = UserManager()
def set_password(self, raw_password):
self.password = make_password(raw_password)
self._password = raw_password
class Student(CustomUser):
student = StudentManager()
class Meta:
proxy = True
class Teacher(CustomUser):
teacher = TeacherManager()
class Meta:
proxy = True
对于其余的,我使用所有默认的 Django 身份验证 URL 和视图,但我尝试修改密码更改视图以确保我不会注销,但问题仍然存在:
urlpatterns = [
path('password_change/', CustomPasswordChangeView.as_view(), name='password_change')
path('', include('django.contrib.auth.urls')),
]
自定义密码更改视图:
class CustomPasswordChangeView(auth.views.PasswordChangeView):
template_name = "registration/password_change_form.html"
success_url = reverse_lazy("password_change_done")
def form_valid(self, form):
response = super().form_valid(form)
update_session_auth_hash(self.request, form.user)
return response
即使更改了form_valid方法,提交表单时我仍然处于注销状态。我输入旧的电子邮件和密码,然后被重定向到password_change_done视图,并且密码没有更改。
最后,我确保将以下内容添加到设置中: AUTH_USER_MODEL = "帐户.自定义用户"
在评论告诉我问题无法重现后,我发现了问题:我没有包含在问题中的保存功能。
def save(self, *args, **kwargs):
if not self.pk:
super().save(*args, **kwargs)
try:
self.base_group.user_set.add(self)
except:
pass
这本应确保用户始终属于正确的组,但它会干扰密码更改。感谢所有评论和回复的人。
看来您已经在 Django 中正确定义了自定义用户模型,并实现了自定义密码更改视图。但是,您可以进行一些修改,以确保密码更改过程按预期进行。
from django.contrib.auth import views as auth_views
urlpatterns = [
path('password_change/', auth_views.PasswordChangeView.as_view(template_name="registration/password_change_form.html", success_url=reverse_lazy("password_change_done")), name='password_change'),
path('password_change_done/', auth_views.PasswordChangeDoneView.as_view(template_name="registration/password_change_done.html"), name='password_change_done'),
# Other authentication URLs
]
进行这些修改后,再次尝试密码更改过程,看看问题是否得到解决。