ubernostrum / django-registration

An extensible user-registration app for Django.
https://django-registration.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
924 stars 241 forks source link

New "Password-based authentication" form field displays in Django 5.1 #245

Open simonw opened 2 months ago

simonw commented 2 months ago

I upgraded to Django 5.1 and now my registration form looks like this:

CleanShot 2024-08-13 at 12 38 22@2x

That confusing "Password-based authentication" field is new - it looks like it was caused by this change to Django:

simonw commented 2 months ago

Looks like this is the cause of the bug: https://github.com/ubernostrum/django-registration/blob/b5ce7d0d90ac34bf0c30e3413bbb817ffce6e4cc/src/django_registration/forms.py#L24-L28

That class inherits from django.contrib.auth.forms.UserCreationForm which now includes the new usable_password form field: https://github.com/django/django/blame/b99c608ea10cabc97a6b251cdb6e81ef2a83bdcf/django/contrib/auth/forms.py#L196-L203

simonw commented 2 months ago

I used this workaround in my own project for the moment:

diff --git a/core/views.py b/core/views.py
index 0c8991d..b7c8d40 100644
--- a/core/views.py
+++ b/core/views.py
@@ -15,6 +15,7 @@ from django.contrib.admin.views.decorators import staff_member_required
 from django.shortcuts import get_object_or_404, render
 from django.conf import settings
 from django.utils.safestring import mark_safe
+from django_registration.forms import RegistrationForm
 from django_registration.backends.activation.views import (
     RegistrationView as BaseRegistrationView,
 )
@@ -174,10 +175,15 @@ def homepage(request):
     return render(request, "homepage.html")

+class CustomRegisterForm(RegistrationForm):
+    usable_password = None
+
+
 class RegistrationView(BaseRegistrationView):
     template_name = "register.html"
     email_subject_template = "register_activation_email_subject.txt"
     email_body_template = "register_activation_email_body.txt"
+    form_class = CustomRegisterForm

     def get(self, request, *args, **kwargs):
         if request.user.is_authenticated:
ubernostrum commented 2 months ago

I'm already planning to give up on UserCreationForm for the next (5.1-compatible) release. Just need to find the time to actually rewrite the thing from scratch and in a way that doesn't randomly blow up at import time whenever someone uses a sufficiently-custom user model.

ubernostrum commented 2 months ago

Also I feel like probably the Django docs should be updated to clarify that UserCreationForm is now essentially an admin-only form class.

simonw commented 2 months ago

I'm already planning to give up on UserCreationForm for the next (5.1-compatible) release. Just need to find the time to actually rewrite the thing from scratch and in a way that doesn't randomly blow up at import time whenever someone uses a sufficiently-custom user model.

That sounds good to me.

simonw commented 2 months ago

Also I feel like probably the Django docs should be updated to clarify that UserCreationForm is now essentially an admin-only form class.

Opened an issue for that here: https://code.djangoproject.com/ticket/35678

ubernostrum commented 2 months ago

Forum discussion: https://forum.djangoproject.com/t/the-purpose-of-usercreationform/33836

nessita commented 2 months ago

This is going to be fixed in Django main via https://github.com/django/django/pull/18484 (and then backported to 5.1 since it's considered a release blocker). Thank you everyone for your contributions!

ubernostrum commented 2 months ago

WIP of removing django-registration's dependency on UserCreationForm is in this branch: https://github.com/ubernostrum/django-registration/tree/remove-usercreationform