Adding Superusers to Admin Group by Signals (and Testing)

Hi, in my project, I want to add all superusers automatically to the Admin group.

I’ve tried different approaches, and at this moment it works correctly only when I use signals connected with the ‘transaction.on_commit’ command (I found that method on the stackoverflow with a similar problem, because ‘normal’ signals without anything else didn’t work).

During manual testing, everything works fine, but my unit tests don’t pass at all, as though superusers weren’t being added to the Admin group automatically, although I’m pretty sure they are…

I have no idea how to test it, and I’m not completely sure in if my code in the signals file is correct.


This is the code from signals.py:

from django.db.models.signals import post_save
from django.db import transaction
from django.dispatch import receiver
from django.contrib.auth.models import Group

from .models import User

@receiver(post_save, sender=User)
def add_to_admin_group(sender, instance, **kwargs):
    if instance.is_superuser and not instance.groups.filter(name='admin').exists():
        admin_group, created = Group.objects.get_or_create(name='admin')
        transaction.on_commit(lambda: instance.groups.add(admin_group))

@receiver(post_save, sender=User)
def remove_from_admin_group(sender, instance, **kwargs):
    if not instance.is_superuser and instance.groups.filter(name='admin').exists():
        admin_group = Group.objects.get(name='admin')
        transaction.on_commit(lambda: instance.groups.remove(admin_group))

And also my temporary test:

class SignalsTestCase(TestCase):
    def test_add_to_admin_group(self):
        user = User.objects.create(username='testuser', password='testpassword', is_superuser=True)
        admin_group, created = Group.objects.get_or_create(name='admin')
        self.assertTrue(admin_group in user.groups.all())

In which directory does that signals.py file reside?

Did you register it in your AppConfig class as described in the green note box within the docs for receiver?

It appears that you’re using a custom User model, do you have your settings.py file set correctly for that?

Are you consistent with your references to the User model between your tests and your code?

  1. The signals.py file is located in the “accounts” app directory that contains my custom User model.

  2. Yes, I registered it, everything is fine with this.

  3. Yes, my custom User model is working correctly. I have configured my ‘settings.py’ file with the following command: AUTH_USER_MODEL = 'accounts.User' .

  4. Yes, I am pretty sure of that.