#32897: create_user() does not raise ValidationError
----------------------------------------+------------------------
Reporter: adamckay | Owner: nobody
Type: Bug | Status: new
Component: contrib.auth | Version: 3.2
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
----------------------------------------+------------------------
The `django.contrib.auth.models.UserManager.create_user()` function does
not perform validation checking of the user object prior to saving to the
database.
The documentation
([https://docs.djangoproject.com/en/3.2/ref/contrib/auth/#django.contrib.auth.models.UserManager.create_user])
implies this is the canonical way to create a user object and indeed it
performs functions to normalize the email address and username as well as
setting an unusable password, however the object is not validated using
`full_clean()` which results in an object that has validation errors
attempting to be committed to the database raising an `IntegrityError`
rather than a `ValidationError`.
This impacts the ability to add errors to any forms which use
`create_user()` as the `IntegrityError` does not return a user-friendly
message, nor is it applied to a field element.
Reproduction steps in a Django shell:
{{{
>>> from django.contrib.auth.models import User
>>> User.objects.create_user('example')
<User: example>
>>> User.objects.create_user('example')
Traceback (most recent call last):
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/backends/sqlite3/base.py", line 423, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: UNIQUE constraint failed: auth_user.username
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/contrib/auth/models.py", line 152, in create_user
return self._create_user(username, email, password, **extra_fields)
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/contrib/auth/models.py", line 146, in _create_user
user.save(using=self._db)
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/contrib/auth/base_user.py", line 67, in save
super().save(*args, **kwargs)
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/models/base.py", line 726, in save
self.save_base(using=using, force_insert=force_insert,
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/models/base.py", line 763, in save_base
updated = self._save_table(
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/models/base.py", line 868, in _save_table
results = self._do_insert(cls._base_manager, using, fields,
returning_fields, raw)
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/models/base.py", line 906, in _do_insert
return manager._insert(
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/models/query.py", line 1270, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/models/sql/compiler.py", line 1416, in execute_sql
cursor.execute(sql, params)
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/backends/utils.py", line 98, in execute
return super().execute(sql, params)
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/backends/utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False,
executor=self._execute)
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/.pyenv/versions/38-django-core/lib/python3.8/site-
packages/django/db/backends/sqlite3/base.py", line 423, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed:
auth_user.username
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/32897>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/051.f2a22f149fef5094b18a6b4874e83600%40djangoproject.com.