Opened 7 years ago
Last modified 7 months ago
#28608 new Cleanup/optimization
Allow UserCreationForm and UserChangeForm to work with custom user models
Reported by: | Rômulo Collopy | Owned by: | shangdahao |
---|---|---|---|
Component: | contrib.auth | Version: | dev |
Severity: | Normal | Keywords: | user, custom user, auth |
Cc: | Lemuel Formacil, Ülgen Sarıkavak | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
class UserChangeForm(forms.ModelForm): # ... class Meta: model = User
and
class UserCreationForm(forms.ModelForm): class Meta: model = User
could use UserModel
instead of User
. It is already defined in https://github.com/django/django/blob/01c6a3e227b645e8dea97e9befecd23d1d3b8581/django/contrib/auth/forms.py#L20 and is used in other forms of the same package.
This would allow Django Registration and other packages that use these forms to work out of the box. And it would allow using them with no need to rewitte as specified at https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#custom-users-and-the-built-in-auth-forms
Attachments (1)
Change History (10)
by , 7 years ago
Attachment: | patch.diff added |
---|
comment:1 by , 7 years ago
Patch needs improvement: | set |
---|---|
Summary: | UserCreationForm and UserChangeForm model using get_user_model → Allow UserCreationForm and UserChangeForm to work with custom user models |
This is a continuation of #19353.
comment:2 by , 7 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:3 by , 7 years ago
Owner: | changed from | to
---|---|
Patch needs improvement: | unset |
Status: | new → assigned |
Since This ticket is related to ticket 28757, I made the changes for this ticket and ticket 28757 in the same commit.
comment:5 by , 6 years ago
Has patch: | unset |
---|---|
Resolution: | fixed |
Status: | closed → new |
In f3fa86a89b3b85242f49b2b9acf58b5ea35acc1f:
Fixed #29449 -- Reverted "Fixed #28757 -- Allowed using contrib.auth forms without installing contrib.auth."
This reverts commit 3333d935d2914cd80cf31f4803821ad5c0e2a51d due to a crash if USERNAME_FIELD isn't a CharField.
comment:6 by , 6 years ago
Another non-standard behavior of the UserCreationForm
when used with a custom user model is if the model has a ManyToManyField
the form will not save the value of the ManyToManyField
. From the documentation:
If your model has a many-to-many relation and you specify
commit=False
when you save a form, Django cannot immediately save the form data for the many-to-many relation. This is because it isn’t possible to save many-to-many data for an instance until the instance exists in the database.
To work around this problem, every time you save a form using
commit=False
, Django adds asave_m2m()
method to yourModelForm
subclass. After you’ve manually saved the instance produced by the form, you can invokesave_m2m()
to save the many-to-many form data.
However, the UserCreationForm.save()
method initially calls the form's save method with commit=False
but then doesn't call the save_m2m
method after committing the instance if commit=True
. The save()
method should be something like this so the form would behave as expected with custom user models with a many-to-many relation:
def save(self, commit=True): user = super().save(commit=False) user.set_password(self.cleaned_data["password1"]) if commit: user.save() self.save_m2m() # added this call to work as expected with models with `ManyToManyField`s return user
comment:7 by , 6 years ago
Cc: | added |
---|
comment:8 by , 9 months ago
Cc: | added |
---|
comment:9 by , 7 months ago
#35484 is a duplicate, this generally tracks the work to make the UserAdmin work for custom user models 👍
patch