Loading django/contrib/auth/management/commands/createsuperuser.py +1 −1 Original line number Diff line number Diff line Loading @@ -115,7 +115,7 @@ class Command(BaseCommand): field = self.UserModel._meta.get_field(field_name) user_data[field_name] = options.get(field_name) while user_data[field_name] is None: raw_value = input(force_str('%s: ' % capfirst(field.verbose_name))) raw_value = input(force_str('%s%s: ' % (capfirst(field.verbose_name), ' (%s.%s)' % (field.rel.to._meta.object_name, field.rel.field_name) if field.rel else ''))) try: user_data[field_name] = field.clean(raw_value, None) except exceptions.ValidationError as e: Loading django/contrib/auth/tests/custom_user.py +26 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,18 @@ class CustomUserManager(BaseUserManager): return u class CustomUserWithFKManager(BaseUserManager): def create_superuser(self, username, email, group, password): user = self.model(username=username, email_id=email, group_id=group) user.set_password(password) user.save(using=self._db) return user class Email(models.Model): email = models.EmailField(verbose_name='email address', max_length=255, unique=True) class CustomUser(AbstractBaseUser): email = models.EmailField(verbose_name='email address', max_length=255, unique=True) is_active = models.BooleanField(default=True) Loading Loading @@ -83,6 +95,20 @@ class CustomUser(AbstractBaseUser): return self.is_admin class CustomUserWithFK(AbstractBaseUser): username = models.CharField(max_length=30, unique=True) email = models.ForeignKey(Email, to_field='email') group = models.ForeignKey(Group) custom_objects = CustomUserWithFKManager() USERNAME_FIELD = 'username' REQUIRED_FIELDS = ['email', 'group'] class Meta: app_label = 'auth' # At this point, temporarily remove the groups and user_permissions M2M # fields from the AbstractUser class, so they don't clash with the related_name # that sets. Loading django/contrib/auth/tests/test_management.py +58 −2 Original line number Diff line number Diff line Loading @@ -9,8 +9,8 @@ from django.contrib.auth import models, management from django.contrib.auth.checks import check_user_model from django.contrib.auth.management import create_permissions from django.contrib.auth.management.commands import changepassword, createsuperuser from django.contrib.auth.models import User from django.contrib.auth.tests.custom_user import CustomUser from django.contrib.auth.models import User, Group from django.contrib.auth.tests.custom_user import CustomUser, CustomUserWithFK, Email from django.contrib.auth.tests.utils import skipIfCustomUser from django.contrib.contenttypes.models import ContentType from django.core import checks Loading Loading @@ -349,6 +349,62 @@ class CreatesuperuserManagementCommandTestCase(TestCase): ) self.assertIs(command.stdin, sys.stdin) @override_settings(AUTH_USER_MODEL='auth.CustomUserWithFK') def test_required_field_with_fk(self): new_io = six.StringIO() group = Group.objects.create(name='mygroup') email = Email.objects.create(email='mymail@gmail.com') call_command( 'createsuperuser', interactive=False, username='user', email='mymail@gmail.com', group=group.pk, stdout=new_io, skip_checks=True, ) command_output = new_io.getvalue().strip() self.assertEqual(command_output, 'Superuser created successfully.') u = CustomUserWithFK._default_manager.get(email=email) self.assertEqual(u.username, "user") self.assertEqual(u.group, group) non_existent_email = 'mymail2@gmail.com' with self.assertRaisesMessage(CommandError, 'email instance with email %r does not exist.' % non_existent_email): call_command( 'createsuperuser', interactive=False, username='user', email=non_existent_email, stdout=new_io, skip_checks=True, ) @override_settings(AUTH_USER_MODEL='auth.CustomUserWithFK') def test_required_fields_with_fk_interactive(self): new_io = six.StringIO() group = Group.objects.create(name='mygroup') email = Email.objects.create(email='mymail@gmail.com') @mock_inputs({'password': "nopasswd", 'username': "user", 'email': "mymail@gmail.com", 'group': group.pk}) def test(self): call_command( 'createsuperuser', interactive=True, stdout=new_io, stdin=MockTTY(), skip_checks=True, ) command_output = new_io.getvalue().strip() self.assertEqual(command_output, 'Superuser created successfully.') u = CustomUserWithFK._default_manager.get(email=email) self.assertEqual(u.username, 'user') self.assertEqual(u.group, group) test(self) class CustomUserModelValidationTestCase(TestCase): @override_settings(AUTH_USER_MODEL='auth.CustomUserNonListRequiredFields') Loading django/db/utils.py +4 −4 Original line number Diff line number Diff line Loading @@ -286,9 +286,9 @@ class ConnectionRouter(object): chosen_db = method(model, **hints) if chosen_db: return chosen_db try: return hints['instance']._state.db or DEFAULT_DB_ALIAS except KeyError: instance = hints.get('instance') if instance is not None and instance._state.db: return instance._state.db return DEFAULT_DB_ALIAS return _route_db Loading docs/releases/1.8.txt +2 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,8 @@ Minor features * The ``max_length`` of :attr:`Permission.name <django.contrib.auth.models.Permission.name>` has been increased from 50 to 255 characters. Please run the database migration. * :attr:`~django.contrib.auth.models.CustomUser.REQUIRED_FIELDS` now supports :class:`~django.db.models.ForeignKey`\s. :mod:`django.contrib.formtools` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Loading Loading
django/contrib/auth/management/commands/createsuperuser.py +1 −1 Original line number Diff line number Diff line Loading @@ -115,7 +115,7 @@ class Command(BaseCommand): field = self.UserModel._meta.get_field(field_name) user_data[field_name] = options.get(field_name) while user_data[field_name] is None: raw_value = input(force_str('%s: ' % capfirst(field.verbose_name))) raw_value = input(force_str('%s%s: ' % (capfirst(field.verbose_name), ' (%s.%s)' % (field.rel.to._meta.object_name, field.rel.field_name) if field.rel else ''))) try: user_data[field_name] = field.clean(raw_value, None) except exceptions.ValidationError as e: Loading
django/contrib/auth/tests/custom_user.py +26 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,18 @@ class CustomUserManager(BaseUserManager): return u class CustomUserWithFKManager(BaseUserManager): def create_superuser(self, username, email, group, password): user = self.model(username=username, email_id=email, group_id=group) user.set_password(password) user.save(using=self._db) return user class Email(models.Model): email = models.EmailField(verbose_name='email address', max_length=255, unique=True) class CustomUser(AbstractBaseUser): email = models.EmailField(verbose_name='email address', max_length=255, unique=True) is_active = models.BooleanField(default=True) Loading Loading @@ -83,6 +95,20 @@ class CustomUser(AbstractBaseUser): return self.is_admin class CustomUserWithFK(AbstractBaseUser): username = models.CharField(max_length=30, unique=True) email = models.ForeignKey(Email, to_field='email') group = models.ForeignKey(Group) custom_objects = CustomUserWithFKManager() USERNAME_FIELD = 'username' REQUIRED_FIELDS = ['email', 'group'] class Meta: app_label = 'auth' # At this point, temporarily remove the groups and user_permissions M2M # fields from the AbstractUser class, so they don't clash with the related_name # that sets. Loading
django/contrib/auth/tests/test_management.py +58 −2 Original line number Diff line number Diff line Loading @@ -9,8 +9,8 @@ from django.contrib.auth import models, management from django.contrib.auth.checks import check_user_model from django.contrib.auth.management import create_permissions from django.contrib.auth.management.commands import changepassword, createsuperuser from django.contrib.auth.models import User from django.contrib.auth.tests.custom_user import CustomUser from django.contrib.auth.models import User, Group from django.contrib.auth.tests.custom_user import CustomUser, CustomUserWithFK, Email from django.contrib.auth.tests.utils import skipIfCustomUser from django.contrib.contenttypes.models import ContentType from django.core import checks Loading Loading @@ -349,6 +349,62 @@ class CreatesuperuserManagementCommandTestCase(TestCase): ) self.assertIs(command.stdin, sys.stdin) @override_settings(AUTH_USER_MODEL='auth.CustomUserWithFK') def test_required_field_with_fk(self): new_io = six.StringIO() group = Group.objects.create(name='mygroup') email = Email.objects.create(email='mymail@gmail.com') call_command( 'createsuperuser', interactive=False, username='user', email='mymail@gmail.com', group=group.pk, stdout=new_io, skip_checks=True, ) command_output = new_io.getvalue().strip() self.assertEqual(command_output, 'Superuser created successfully.') u = CustomUserWithFK._default_manager.get(email=email) self.assertEqual(u.username, "user") self.assertEqual(u.group, group) non_existent_email = 'mymail2@gmail.com' with self.assertRaisesMessage(CommandError, 'email instance with email %r does not exist.' % non_existent_email): call_command( 'createsuperuser', interactive=False, username='user', email=non_existent_email, stdout=new_io, skip_checks=True, ) @override_settings(AUTH_USER_MODEL='auth.CustomUserWithFK') def test_required_fields_with_fk_interactive(self): new_io = six.StringIO() group = Group.objects.create(name='mygroup') email = Email.objects.create(email='mymail@gmail.com') @mock_inputs({'password': "nopasswd", 'username': "user", 'email': "mymail@gmail.com", 'group': group.pk}) def test(self): call_command( 'createsuperuser', interactive=True, stdout=new_io, stdin=MockTTY(), skip_checks=True, ) command_output = new_io.getvalue().strip() self.assertEqual(command_output, 'Superuser created successfully.') u = CustomUserWithFK._default_manager.get(email=email) self.assertEqual(u.username, 'user') self.assertEqual(u.group, group) test(self) class CustomUserModelValidationTestCase(TestCase): @override_settings(AUTH_USER_MODEL='auth.CustomUserNonListRequiredFields') Loading
django/db/utils.py +4 −4 Original line number Diff line number Diff line Loading @@ -286,9 +286,9 @@ class ConnectionRouter(object): chosen_db = method(model, **hints) if chosen_db: return chosen_db try: return hints['instance']._state.db or DEFAULT_DB_ALIAS except KeyError: instance = hints.get('instance') if instance is not None and instance._state.db: return instance._state.db return DEFAULT_DB_ALIAS return _route_db Loading
docs/releases/1.8.txt +2 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,8 @@ Minor features * The ``max_length`` of :attr:`Permission.name <django.contrib.auth.models.Permission.name>` has been increased from 50 to 255 characters. Please run the database migration. * :attr:`~django.contrib.auth.models.CustomUser.REQUIRED_FIELDS` now supports :class:`~django.db.models.ForeignKey`\s. :mod:`django.contrib.formtools` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Loading