I have the following structure of my application in relation to the following apps
project
userprofile
models.py
rbsessions
models.py
In userprofile/models.py I have the following
from __future__ import unicode_literals
from django.conf import settings
from django.utils import timezone
from datetime import datetime
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.template.defaultfilters import slugify
from django.dispatch import receiver
from django.db.models.signals import post_save
from rbsessions.models import Session
class User(AbstractUser):
GENDER_MALE = 'M'
GENDER_FEMALE = 'F'
GENDER_OTHER = 'O'
GENDER_CHOICES = (
(GENDER_MALE, u'Male'),
(GENDER_FEMALE, u'Female'),
(GENDER_OTHER, u'Other'),
)
AMERICAN_GROUP = 'AM'
ASIATIC_GROUP = 'AS'
AFROAMERICAN_GROUP = 'AFA'
EUROPEAN_GROUP = 'EU'
INDIGENOUS = 'IND'
OTHER_GROUP = 'O'
ETHNIC_CHOICES = (
(AMERICAN_GROUP, u'American'),
(ASIATIC_GROUP, u'Asiatic'),
(AFROAMERICAN_GROUP, u'Afroamerican'),
(EUROPEAN_GROUP, u'European'),
(INDIGENOUS, u'Indigenous'),
(OTHER_GROUP, u'Other'),
)
gender = models.CharField(
max_length=1,
choices=GENDER_CHOICES,
default=GENDER_OTHER,)
ethnic_group = models.CharField(
max_length=3,
choices=ETHNIC_CHOICES,
default=OTHER_GROUP)
birth_date = models.DateTimeField(default=timezone.now())
address = models.CharField(max_length=150, blank=False)
phone = models.CharField(verbose_name=u'phone', max_length=25, blank=True)
occupation = models.CharField(max_length=150, blank=False)
country_of_birth = models.CharField(max_length=150, blank=False)
communication_language = models.CharField(max_length=150, blank=False)
is_medical = models.BooleanField(default=False)
is_therapist = models.BooleanField(default=False)
is_patient = models.BooleanField(default=False)
slug = models.SlugField(max_length=100, blank=True)
photo = models.ImageField(upload_to='avatars', blank = False)
def save(self, *args, **kwargs):
user = super(User, self).save( *args, **kwargs)
# Creating and user with medical, patient and therapist profiles
if self.is_medical and not MedicalProfile.objects.filter(user=self).exists()\
and self.is_patient and not PatientProfile.objects.filter(user=self).exists()\
and self.is_therapist and not TherapistProfile.objects.filter(user=self).exists():
medical_profile=MedicalProfile(user=self).save()
patient_profile=PatientProfile(user=self).save()
therapist_profile=TherapistProfile(user=self).save()
#profile.save()
# Creating and user with medical and patient profiles
elif self.is_medical and not MedicalProfile.objects.filter(user=self).exists()\
and self.is_patient and not PatientProfile.objects.filter(user=self).exists():
medical_profile=MedicalProfile(user=self).save()
patient_profile=PatientProfile(user=self).save()
# Creating and user with medical and therapist profiles
elif self.is_medical and not MedicalProfile.objects.filter(user=self).exists()\
and self.is_therapist and not TherapistProfile.objects.filter(user=self).exists():
medical_profile=MedicalProfile(user=self).save()
therapist_profile=TherapistProfile(user=self).save()
# Creating and user with physiotherapist and patient profiles
elif self.is_therapist and not TherapistProfile.objects.filter(user=self).exists()\
and self.is_patient and not PatientProfile.objects.filter(user=self).exists():
therapist_profile = TherapistProfile(user=self).save()
patient_profile = PatientProfile(user=self).save()
# Creating and user with medical profile
elif self.is_medical and not MedicalProfile.objects.filter(user=self).exists():
profile = MedicalProfile(user=self)
profile.save()
# Creating and user with patient profile -- Here --
elif self.is_patient and not PatientProfile.objects.filter(user=self).exists():
profile = PatientProfile(user=self)
profile.save()
encounter = Session(user=self).save()
# Creating and user with therapist profiles
elif self.is_therapist and not TherapistProfile.objects.filter(user=self).exists():
profile = TherapistProfile(user=self)
profile.save()
# We get the profiles user according with their type
def get_medical_profile(self):
medical_profile = None
if hasattr(self, 'medicalprofile'):
medical_profile=self.medicalprofile
return medical_profile
def get_patient_profile(self):
patient_profile = None
if hasattr(self, 'patientprofile'):
patient_profile = self.patientprofile
return patient_profile
def get_therapist_profile(self):
therapist_profile = None
if hasattr(self, 'therapistprofile'):
therapist_profile = self.therapistprofile
return therapist_profile
class Meta:
db_table = 'auth_user'
class MedicalProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
#active = models.BooleanField(default=True)
name = models.CharField(max_length=64)
specialty = models.CharField(max_length=64)
def __str__(self):
return '%s %s' % (self.user.first_name, self.user.last_name)
class PatientProfile(models.Model):
STATUS_SINGLE = 'S'
STATUS_MARRIED = 'M'
STATUS_WIDOW = 'W'
STATUS_OTHER = 'O'
STATUS_CHOICES = (
(STATUS_SINGLE, u'Single'),
(STATUS_MARRIED, u'Married'),
(STATUS_WIDOW, u'Widow'),
(STATUS_OTHER, u'Other'),
)
PRIMARY_LEVEL = 'PRI'
SECONDARY_LEVEL = 'SEC'
UNIVERSITARY_LEVEL = 'UNI'
MASTER_LEVEL = 'MAS'
PHD_LEVEL = 'PHD'
LEVEL_CHOICES = (
(PRIMARY_LEVEL, u'Primary'),
(SECONDARY_LEVEL, u'Secondary'),
(UNIVERSITARY_LEVEL, u'University'),
(MASTER_LEVEL, u'Master'),
(PHD_LEVEL, u'PhD'),
)
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
#active = models.BooleanField(default=True)
name = models.CharField(max_length=64)
blood_type = models.CharField(max_length=4, blank=False)
marital_status = models.CharField(max_length=1, choices=STATUS_CHOICES, blank=False)
educational_level = models.CharField(max_length=3, choices=LEVEL_CHOICES, blank=False)
care_provider = models.CharField(max_length=64, blank=False)
time_of_evolution = models.CharField(max_length=64, blank=False)
affected_limb = models.CharField(max_length=64, blank=False)
diagnostic = models.TextField(blank=True)
managing_organization = models.CharField(max_length=64, blank=False)
def __str__(self):
return '%s %s' % (self.user.first_name, self.user.last_name)
class TherapistProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
#active = models.BooleanField(default=True)
name = models.CharField(max_length=64)
specialty = models.CharField(max_length=64)
def __str__(self):
return '%s %s' % (self.user.first_name, self.user.last_name)
# Enter the username as slug field
@receiver(post_save, sender = settings.AUTH_USER_MODEL)
def post_save_user(sender, instance, **kwargs):
slug = slugify(instance.username)
User.objects.filter(pk=instance.pk).update(slug=slug)
In rbsessions/models.py
I have a class called Session
from django.db import models
from django.utils import timezone
# Create your models here.
class Session(models.Model):
STATUS_PLANNED = 'PLA'
STATUS_ARRIVED = 'ARR'
STATUS_IN_PROGRESS = 'PRO'
STATUS_ON_LEAVE = 'ONL'
STATUS_FINISHED = 'FIN'
STATUS_CANCELLED = 'CAN'
STATUS_CHOICES = (
(STATUS_PLANNED, u'Planned'),
(STATUS_ARRIVED, u'Arrived'),
(STATUS_IN_PROGRESS, u'In progress'),
(STATUS_FINISHED, u'Finished'),
(STATUS_CANCELLED, u'Cancelled'),
)
description = models.TextField(blank=False)
date_session = models.DateTimeField(default=timezone.now())
status = models.CharField(max_length=3,
choices=STATUS_CHOICES,
default=STATUS_PLANNED)
participants = models.TextField(blank=False)
period = models.CharField(max_length=25,blank=True)
game_levels = models.TextField(blank=True)
iterations = models.PositiveIntegerField(blank=True)
# Number of repetitions of each level or game (definir)
movements = models.TextField(blank=False)
games = models.TextField(blank=False)
medical = models.ForeignKey('userprofile.MedicalProfile')
patient = models.ForeignKey('userprofile.PatientProfile')
therapist = models.ForeignKey('userprofile.TherapistProfile')
As Cesar says in the first answer to this question, I have a loop or circular import type because from each models.py
of each application, I am importing models from the other. So I get this error:
(nrb_dev)➜ project-system git:(dev) ✗ python manage.py runserver
Performing system checks...
System check identified 2 issues (0 silenced).
January 20, 2016 - 14:11:40
Django version 1.9, using settings 'neurorehabilitation.settings.development'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[20/Jan/2016 14:11:42] "GET /admin/ HTTP/1.1" 200 6976
[20/Jan/2016 14:13:03] "GET /admin/rbsessions/session/ HTTP/1.1" 200 3715
[20/Jan/2016 14:13:03] "GET /admin/jsi18n/ HTTP/1.1" 200 3189
[20/Jan/2016 14:13:07] "GET /admin/ HTTP/1.1" 200 6976
[20/Jan/2016 14:13:09] "GET /admin/userprofile/therapistprofile/ HTTP/1.1" 200 5368
[20/Jan/2016 14:13:09] "GET /admin/jsi18n/ HTTP/1.1" 200 3189
[20/Jan/2016 14:13:11] "GET /admin/userprofile/ HTTP/1.1" 200 3734
[20/Jan/2016 14:13:14] "GET /admin/userprofile/patientprofile/ HTTP/1.1" 200 7044
[20/Jan/2016 14:13:14] "GET /admin/jsi18n/ HTTP/1.1" 200 3189
[20/Jan/2016 14:17:53] "GET /admin/ HTTP/1.1" 200 6976
Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x7f3f7a342378>
Traceback (most recent call last):
File "/home/bgarcial/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/utils/autoreload.py", line 226, in wrapper
fn(*args, **kwargs)
File "/home/bgarcial/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/core/management/commands/runserver.py", line 109, in inner_run
autoreload.raise_last_exception()
File "/home/bgarcial/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/utils/autoreload.py", line 249, in raise_last_exception
six.reraise(*_exception)
File "/home/bgarcial/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/home/bgarcial/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/utils/autoreload.py", line 226, in wrapper
fn(*args, **kwargs)
File "/home/bgarcial/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/__init__.py", line 18, in setup
apps.populate(settings.INSTALLED_APPS)
File "/home/bgarcial/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/apps/registry.py", line 108, in populate
app_config.import_models(all_models)
File "/home/bgarcial/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/apps/config.py", line 202, in import_models
self.models_module = import_module(models_module_name)
File "/home/bgarcial/.virtualenvs/nrb_dev/lib/python3.4/importlib/__init__.py", line 109, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
File "<frozen importlib._bootstrap>", line 2226, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 1200, in _load_unlocked
File "<frozen importlib._bootstrap>", line 1129, in _exec
File "<frozen importlib._bootstrap>", line 1471, in exec_module
File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
File "/home/bgarcial/workspace/neurorehabilitation-system/rbsessions/models.py", line 3, in <module>
from userprofile.models import MedicalProfile,TherapistProfile, PatientProfile
File "/home/bgarcial/workspace/neurorehabilitation-system/userprofile/models.py", line 17, in <module>
from rbsessions.models import Session
ImportError: cannot import name 'Session'
UPDATE
The foreign keys that I have are in the Session class where I import the models MedicalProfile
, TherapistProfile
, PatientProfile
.
In the class User
I called the model Session
but not as a foreign key but as its class, so that when a user with a patient profile is created, a record of a Rehabilitation session (Session) for that patient is also created. So I'm calling it this way
from rbsessions.models import Session
class User(AbstractUser):
def save(self, *args, **kwargs):
user = super(User, self).save( *args, **kwargs)
# Creating and user with patient profile
if self.is_patient and not PatientProfile.objects.filter(user=self).exists():
profile = PatientProfile(user=self)
profile.save()
encounter = Session(user=self).save()
And that's where my mistake comes fromfrom rbsessions.models import Session
ImportError: cannot import name 'Session'
I have my doubts though if I can tell Django to instantiate a rehab session (given by the Session class) like that.
It seems to me that you have problems because you are doing a circular import,
rbsessions/models.py
you are importing models fromuserprofile/models.py
and vice versa, it would be good if you show the complete code of the models.If what you're trying to do is use it for
ForeignKey
s, you can comment out the lines of the imports and use the textual notation. For example:Update
Don't worry, what I would do in your case is to pass everything to textual notation for the fields that are foreign keys, this way you avoid problems with imports:
With this, in your files
models.py
you should no longer havefrom app.models import X
anywhere.