The purpose of UserCreationForm

django.contrib.auth.forms.UserCreationForm has been around and documented forever, and it seems based on the suggested duplicate threads that popped up when I started writing this, and from some general searching about, that it is fairly widely used in user-creation or user-registration views. It also has long been used as a base by the user-registration forms in django-registration (a popular third-party user-registration app I maintain) and its various forks.

But as of Django 5.1 that’s a bit more difficult; ticket 34429 added what is effectively an admin-only feature to UserCreationForm (well, it added it to BaseUserCreationForm, and then UserCreationForm inherits it), which means that now any use of UserCreationForm outside of an admin-interface (whether the stock django.contrib.admin or a custom administrative interface) context will display the extra “usable password” field.

The documentation does not really mention this or otherwise indicate that UserCreationForm is intended only for administrative use.

So I guess it’s time for it to do that, and to clarify exactly what this form is for: is it only for trusted superusers working in an admin interface? Or is it meant to a generic base for many types of user-creation forms including self-service account registration? Because if it’s the latter, then some way of turning off the new “usable password” field needs to be provided. And if it’s the former, that needs to be clearly communicated.

For django-registration I was already planning to stop relying on UserCreationForm for other reasons (it hard-codes the default User model, which has a tendency to cause import-time crashes for people who use their own sufficiently custom user models). But it’d be nice to have this properly clarified for the future anyway (and maybe to have some of the infrastructure of UserCreationForm split out in a way that third-party apps like django-registration could reuse, so that I don’t have to reimplement all that security-sensitive logic from scratch and try to maintain parity with Django’s implementation).

1 Like

Ooh. Good spot James. At first glance this seems like a regression… it’s an unintended change in documented behaviour.

If we agree that then the “way to turn off the new field” would be required, as a release blocker for 5.1.

Certainly it’s a documentation issue at least, but it feels stronger than that to me.

Simon already opened a ticket for this:

https://code.djangoproject.com/ticket/35678

If the intent is for UserCreationForm to be usable in non-admin contexts, I think probably Tim’s suggestion there that the admin gain its own subclass of the form with the desired behavior is the way to go – then people who want that can use the admin version, and others can stick to UserCreationForm.

1 Like

Great. That seems spot on.

+1.

Thanks for raising this James.

+1 from me too. Good catch James!

Thank you everyone for your input, I agree with the severity and I will ensure we release a fix in the next patch release.

@fsbraun Would you like and have availability to work in this? Otherwise I’ll take it.

1 Like

@nessita Yes, this makes absolute sense.

I agree with Tim Graham, to create an AdminUserCreationForm as a subclass of the UserCreationForm and move the usable_password field from the BaseUserCreationForm to the AdminUserCreationForm. The admin (and anybody who would like to have unusable passwords to be in the form) then will use the AdminUserCreationForm instead of the UserCreationForm.

1 Like

I ran into this and quickly added to following my subclass.

# Remove the option to create an account with an unusable password.
usable_password = None

Didn’t even think of raising this, but I do agree that not having to do this would be nice.

1 Like