# Circular import when using get\_user\_model() inside a custom BaseUserManager

**URL:** <https://forum.djangoproject.com/t/circular-import-when-using-get-user-model-inside-a-custom-baseusermanager/45297>\
**Category:** Mystery Errors\
**Created:** [June 15, 2026, 2:05pm UTC](https://forum.djangoproject.com/t/circular-import-when-using-get-user-model-inside-a-custom-baseusermanager/45297 "2026-06-15T14:05:59Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![HushmKun](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/hushmkun/32/26004_2.png) [@HushmKun](https://forum.djangoproject.com/u/HushmKun)\
**Post date:** [June 15, 2026, 2:05pm UTC](https://forum.djangoproject.com/t/circular-import-when-using-get-user-model-inside-a-custom-baseusermanager/45297/1 "2026-06-15T14:05:59Z")

</div>

Hi everyone!

I have been creating a sample Saas and wanted to organize my project from the start in a neat & tidy way. so I decided to move the apps I create into apps directory in the following way:

```bash
D:.
ª uv.lock
ª           
+---.vscode
ª settings.json
ª       
+---apps
ª ª __init__.py
ª ª   
ª +---accounts
ª ª ª admin.py
ª ª ª apps.py
ª ª ª forms.py
ª ª ª manager.py
ª ª ª models.py
ª ª ª tasks.py
ª ª ª tests.py
ª ª ª theme.py
ª ª ª urls.py
ª ª ª views.py
ª ª ª __init__.py
ª ª ª   
ª ª +---migrations
ª ª ª 0001_initial.py
ª ª ª 0002_remove_user_username.py
ª ª ª 0003_user_avatar_user_preferences.py
ª ª ª 0004_alter_user_preferences.py
ª ª ª __init__.py
ª ª ª       
ª ª           
ª +---billing
ª ª ª admin.py
ª ª ª apps.py
ª ª ª mixins.py
ª ª ª models.py
ª ª ª services.py
ª ª ª signals.py
ª ª ª tasks.py
ª ª ª tests.py
ª ª ª urls.py
ª ª ª views.py
ª ª ª webhooks.py
ª ª ª __init__.py
ª ª ª   
ª ª +---migrations
ª ª ª 0001_initial.py
ª ª ª 0002_alter_subscription_options.py
ª ª ª 0003_subscription_screenshots_used.py
ª ª ª 0004_rename_price_cents_plan_price_usd.py
ª ª ª 0005_plan_plan_desc_plan_plan_features.py
ª ª ª __init__.py
ª ª           
ª +---cards
ª ª ª admin.py
ª ª ª apps.py
ª ª ª browser.py
ª ª ª extractor.py
ª ª ª models.py
ª ª ª tasks.py
ª ª ª tests.py
ª ª ª urls.py
ª ª ª views.py
ª ª ª __init__.py
ª ª ª   
ª ª +---migrations
ª ª ª 0001_initial.py
ª ª ª 0002_card_platform_alter_card_image.py
ª ª ª 0003_platform_card_completed_at_card_error_message_and_more.py
ª ª ª 0004_alter_card_platform.py
ª ª ª 0005_card_post_datetime.py
ª ª ª 0006_alter_card_post_datetime.py
ª ª ª 0007_platform_extractor_key.py
ª ª ª __init__.py
ª ª   
ª +---dashboard
ª ª ª admin.py
ª ª ª apps.py
ª ª ª forms.py
ª ª ª models.py
ª ª ª tests.py
ª ª ª urls.py
ª ª ª views.py
ª ª ª __init__.py
ª ª ª   
ª ª +---migrations
ª ª ª __init__.py
ª ª           
ª +---landing
ª ª ª admin.py
ª ª ª apps.py
ª ª ª models.py
ª ª ª tests.py
ª ª ª urls.py
ª ª ª views.py
ª ª ª __init__.py
ª ª ª   
ª ª +---migrations
ª ª ª __init__.py
ª ª ª       
ª           
+---config
ª ª asgi.py
ª ª Celery.py
ª ª context_processors.py
ª ª settings.py
ª ª test_runner.py
ª ª urls.py
ª ª wsgi.py
ª ª __init__.py
ª   
+---logs
+---media
+---static
+---templates                

```

Now this led to some complications which I have worked my way around.

Now I was creating a new UserManager instead of the default one, so I did the following

```python
# apps/accounts/manager.py

from django.contrib.auth.base_user import BaseUserManager
from django.contrib.auth import get_user_model

User = get_user_model()

class UserManager(BaseUserManager):

    def normalize_email(cls, email):
        """
        Normalize the email address by lowercasing the domain part of it.
        """
        email = email or ""
        try:
            email_name, domain_part = email.strip().rsplit("@", 1)
        except ValueError:
            pass
        else:
            email = email_name.lower() + "@" + domain_part.lower()
        return email

    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError("The given email must be set")
        email = self.normalize_email(email)
        user = User(email=email, **extra_fields)
        user.password = make_password(password)
        return user

    def create_superuser(self, username, email=None, password=None, **extra_fields):
        extra_fields.setdefault("is_staff", True)
        extra_fields.setdefault("is_superuser", True)

        if extra_fields.get("is_staff") is not True:
            raise ValueError("Superuser must have is_staff=True.")
        if extra_fields.get("is_superuser") is not True:
            raise ValueError("Superuser must have is_superuser=True.")

        return self.create_user(email, password, **extra_fields)

```

which introduced circular dependency and raised a strange error @ `AUTH_USER_MODEL`.

```python
# settings.py

INSTALLED_APPS = [
    ...
    'apps.landing',
    'apps.dashboard',
    'apps.accounts',
    'apps.cards',
    'apps.billing'
]

...

AUTH_USER_MODEL = 'accounts.User'

```

this raises the following error:

```auto
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'accounts.User' that has not been installed

```

of course I tried

```auto
AUTH_USER_MODEL = 'apps.accounts.User'

```

which raises

```auto
ValueError: Invalid model reference 'apps.accounts.User'. String model references must be of the form 'app_label.ModelName'.

```

I don’t understand how `get_user_model` could mess up all these, and how to fix this problem?  
Thanks for the help.

---

<div class="post-metadata">

**Author:** ![massover](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/massover/32/1792_2.png) [@massover](https://forum.djangoproject.com/u/massover)\
**Post date:** [June 15, 2026, 9:05pm UTC](https://forum.djangoproject.com/t/circular-import-when-using-get-user-model-inside-a-custom-baseusermanager/45297/2 "2026-06-15T21:05:47Z")

</div>

It looks like you have an `apps.py` in your accounts app. What is the [label](https://docs.djangoproject.com/en/6.0/ref/applications/#django.apps.AppConfig.label) set to on the AppConfig?

---

<div class="post-metadata">

**Author:** ![antoinehumbert](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/antoinehumbert/32/14851_2.png) [@antoinehumbert](https://forum.djangoproject.com/u/antoinehumbert)\
**Post date:** [June 15, 2026, 9:30pm UTC](https://forum.djangoproject.com/t/circular-import-when-using-get-user-model-inside-a-custom-baseusermanager/45297/3 "2026-06-15T21:30:08Z")

</div>

Because your User model probably import its manager. I guess you have in models.py, something like:

```python
from .manager import UserManager

class User(...):
    objects = UserManager()

```

When the models.py module is imported (which is done when resolving setting `AUTH_USER_MODEL`), it begins by importing the manager.py module (as per the import line), which calls `get_user_model()` which imports apps.accounts.models.py, hence the circular import.

In your manager, you do not need to explicitly use the User class returned by `get_user_model`. The manager already has a reference to the model using `self.model`. So, by replacing the use of `User` by `self.model` and removing call to `get_user_model`, it should avoid the circular import

---

<div class="post-metadata">

**Author:** ![HushmKun](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/hushmkun/32/26004_2.png) [@HushmKun](https://forum.djangoproject.com/u/HushmKun)\
**Post date:** [June 15, 2026, 9:51pm UTC](https://forum.djangoproject.com/t/circular-import-when-using-get-user-model-inside-a-custom-baseusermanager/45297/4 "2026-06-15T21:51:47Z")

</div>

None, only set the name into ‘apps.accounts’

---

<div class="post-metadata">

**Author:** ![HushmKun](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/hushmkun/32/26004_2.png) [@HushmKun](https://forum.djangoproject.com/u/HushmKun)\
**Post date:** [June 15, 2026, 9:53pm UTC](https://forum.djangoproject.com/t/circular-import-when-using-get-user-model-inside-a-custom-baseusermanager/45297/5 "2026-06-15T21:53:46Z")

</div>

It worked, thanks for your help, I totally missed the `self.model` attribute.
