I am trying to create a specialized membership application using django. I am having some trouble planning out my app + table structure and data flow. For example: I have the basic django user model. I am using a package called "allauth" and I have created a "Profile" model that holds basic person info. I have tied all that together and it works for sign-up, account verification, logout and getting to a primitive "user page". The next step is where I am getting a bit lost and getting an import error.
The person that creates a log-in must be 18 years old or more. That person might be an adult member or the parent of one or more youth members or be both a parent and an adult member. In any case the logged in person is thought of as being financially responsible for the member-account(s) associated with them. There is also a case where more than one log-in person (like spouses) could share multiple "accounts" between them. For example, either person in an adult couple could be financially responsible for paying the bills.
So, for a given log-in "profile" I need a ManyToMany
relation to an "accounts" table. An account can have ManyToMany
relations to one or more member records and member "records" should live in the "profile" table but might not have login records in the "User" table.
Now we approach my problem. With the allauth
config and an account_adaptor
method I have the django "User" model attached to the account profile, a la: (trimmed for brevity)
# PROFILE
import uuid
from auditlog.models import AuditlogHistoryField
from auditlog.registry import auditlog
from django.contrib.auth.models import User
from django.db import models
from .account import Account
class Profile(models.Model):
id = models.UUIDField(
max_length=32,
default=uuid.uuid4,
editable=False,
primary_key=True,
blank=False,
null=False,
)
user = models.OneToOneField(
User,
on_delete=models.CASCADE,
unique=True,
blank=True,
null=True,
)
name_info = ...
birthdate = models.DateField(
blank=False,
null=False
)
address_info = ...
# ACCOUNT
import uuid
from auditlog.models import AuditlogHistoryField
from auditlog.registry import auditlog
from django.db import models
from .student import Student
from Billing.models.payment import Payment
class Account(models.Model):
id = models.UUIDField(
max_length=32,
default=uuid.uuid4,
editable=False,
primary_key=True,
blank=False,
null=False,
)
students = models.ManyToManyField(Student)
payments = models.ManyToManyField(Payment)
# STUDENT
import uuid
from auditlog.models import AuditlogHistoryField
from auditlog.registry import auditlog
from django.db import models
from .profile import Profile
class Student(models.Model):
id = models.UUIDField(
max_length=32,
default=uuid.uuid4,
editable=False,
primary_key=True,
blank=False,
null=False,
)
profile = models.OneToOneField(
Profile,
on_delete=models.CASCADE,
unique=True,
blank=False,
null=False,
)
When I do makemigrations
I get the stacktrace:
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "C:\me\myProject\venv\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
utility.execute()
File "C:\me\myProject\venv\lib\site-packages\django\core\management\__init__.py", line 357, in execute
django.setup()
File "C:\me\myProject\venv\lib\site-packages\django\__init__.py", line 24, in setup
apps.populate(settings.INSTALLED_APPS)
File "C:\me\myProject\venv\lib\site-packages\django\apps\registry.py", line 112, in populate
app_config.import_models()
File "C:\me\myProject\venv\lib\site-packages\django\apps\config.py", line 198, in import_models
self.models_module = import_module(models_module_name)
File "C:\Program Files (x86)\Python3-6-5\lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "C:\me\myProject\myApp\Manager\models\__init__.py", line 2, in <module>
from .group_list import *
File "C:\me\myProject\myApp\Manager\models\group_list.py", line 5, in <module>
from Members.models.profile import Profile
File "C:\me\myProject\myApp\Members\models\__init__.py", line 1, in <module>
from .profile import *
File "C:\me\myProject\myApp\Members\models\profile.py", line 8, in <module>
from .account import Account
File "C:\me\myProject\myApp\Members\models\account.py", line 7, in <module>
from .student import Student
File "C:\me\myProject\myApp\Members\models\student.py", line 7, in <module>
from .profile import Profile
ImportError: cannot import name 'Profile'
My thought is that this is creating some circular linking that django doesn't but I don't understand this well enought to work around it.
Thoughts: the Student table could be its own table but that feels wastful as the Profile table already has the necessary columns
Edit
I think this is a duplicate of this post