diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index c9c202355d2..5fec99a783c 100644 --- a/django/contrib/auth/models.py +++ b/django/contrib/auth/models.py @@ -295,10 +295,12 @@ class PermissionsMixin(models.Model): groups = models.ManyToManyField(Group, verbose_name=_('groups'), blank=True, help_text=_('The groups this user belongs to. A user will ' 'get all permissions granted to each of ' - 'his/her group.')) + 'his/her group.'), + related_name="user_set", related_query_name="user") user_permissions = models.ManyToManyField(Permission, verbose_name=_('user permissions'), blank=True, - help_text='Specific permissions for this user.') + help_text='Specific permissions for this user.', + related_name="user_set", related_query_name="user") class Meta: abstract = True diff --git a/django/contrib/auth/tests/test_custom_user.py b/django/contrib/auth/tests/test_custom_user.py index 0f6ebbda558..394baa32042 100644 --- a/django/contrib/auth/tests/test_custom_user.py +++ b/django/contrib/auth/tests/test_custom_user.py @@ -4,7 +4,9 @@ from django.contrib.auth.models import ( AbstractBaseUser, AbstractUser, UserManager, - PermissionsMixin + PermissionsMixin, + Group, + Permission, ) @@ -81,6 +83,20 @@ class CustomUser(AbstractBaseUser): return self.is_admin +# 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. + +old_au_local_m2m = AbstractUser._meta.local_many_to_many +old_pm_local_m2m = PermissionsMixin._meta.local_many_to_many +groups = models.ManyToManyField(Group, blank=True) +groups.contribute_to_class(PermissionsMixin, "groups") +user_permissions = models.ManyToManyField(Permission, blank=True) +user_permissions.contribute_to_class(PermissionsMixin, "user_permissions") +PermissionsMixin._meta.local_many_to_many = [groups, user_permissions] +AbstractUser._meta.local_many_to_many = [groups, user_permissions] + + # The extension user is a simple extension of the built-in user class, # adding a required date_of_birth field. This allows us to check for # any hard references to the name "User" in forms/handlers etc. @@ -178,3 +194,7 @@ class CustomUserBadRequiredFields(AbstractBaseUser): class Meta: app_label = 'auth' + +# Undo swap hack +AbstractUser._meta.local_many_to_many = old_au_local_m2m +PermissionsMixin._meta.local_many_to_many = old_pm_local_m2m