﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
36703	Undocumented change of SetPasswordForm in django 5.1 release notes	Laurent Bergeron		"Since version 5.1 of django, django.contrib.auth.forms.SetPasswordForm looks like this:


{{{
class SetPasswordForm(SetPasswordMixin, forms.Form):
    """"""
    A form that lets a user set their password without entering the old
    password
    """"""

    new_password1, new_password2 = SetPasswordMixin.create_password_fields(
        label1=_(""New password""), label2=_(""New password confirmation"")
    )

    def __init__(self, user, *args, **kwargs):
        self.user = user
        super().__init__(*args, **kwargs)

    def clean(self):
        self.validate_passwords(""new_password1"", ""new_password2"")
        self.validate_password_for_user(self.user, ""new_password2"")
        return super().clean()

    def save(self, commit=True):
        return self.set_password_and_save(self.user, ""new_password1"", commit=commit)
}}}

Before version 5.1 though, it looked like this:

{{{
class SetPasswordForm(forms.Form):
    """"""
    A form that lets a user set their password without entering the old
    password
    """"""

    error_messages = {
        ""password_mismatch"": _(""The two password fields didn’t match.""),
    }
    new_password1 = forms.CharField(
        label=_(""New password""),
        widget=forms.PasswordInput(attrs={""autocomplete"": ""new-password""}),
        strip=False,
        help_text=password_validation.password_validators_help_text_html(),
    )
    new_password2 = forms.CharField(
        label=_(""New password confirmation""),
        strip=False,
        widget=forms.PasswordInput(attrs={""autocomplete"": ""new-password""}),
    )

    def __init__(self, user, *args, **kwargs):
        self.user = user
        super().__init__(*args, **kwargs)

    def clean_new_password2(self):
        password1 = self.cleaned_data.get(""new_password1"")
        password2 = self.cleaned_data.get(""new_password2"")
        if password1 and password2 and password1 != password2:
            raise ValidationError(
                self.error_messages[""password_mismatch""],
                code=""password_mismatch"",
            )
        password_validation.validate_password(password2, self.user)
        return password2

    def save(self, commit=True):
        password = self.cleaned_data[""new_password1""]
        self.user.set_password(password)
        if commit:
            self.user.save()
        return self.user
}}}

I can't see this change described anywhere in the 5.1 release note [https://docs.djangoproject.com/en/5.2/releases/5.1/]

Do I have a blind spot and the change is in fact described in the patch note ? If it is not, should it be or is it too small of a change to be part of the release notes?

Personally, it caused some of my tests to fail when I upgraded from 4.2 to 5.2. I had some logic to modify the error messages and it broke because of the change."	Bug	closed	contrib.auth	5.1	Normal	invalid	Authentication, Forms		Unreviewed	0	0	0	0	0	0
