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:
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
# 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.
# settings.py
INSTALLED_APPS = [
...
'apps.landing',
'apps.dashboard',
'apps.accounts',
'apps.cards',
'apps.billing'
]
...
AUTH_USER_MODEL = 'accounts.User'
this raises the following error:
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'accounts.User' that has not been installed
of course I tried
AUTH_USER_MODEL = 'apps.accounts.User'
which raises
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.