﻿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
32897	create_user() does not raise ValidationError	Adam McKay	nobody	"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

}}}
"	Bug	closed	contrib.auth	3.2	Normal	invalid			Unreviewed	0	0	0	0	0	0
