Error importing a model Unhandled exception - can not import name

2

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 type or circular import because of each models.py of each application, I'm importing models from the other. Then 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 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 is also created ( Session) for that patient. 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 error of from rbsessions.models import Session ImportError: cannot import name 'Session' comes from

Although I have my doubts if I can tell Django to create an instance of a rehabilitation session (given by the Session class) in that way.

    
asked by bgarcial 20.01.2016 в 15:58
source

1 answer

2

I think you have problems because you are doing a circular import, since rbsessions/models.py are importing models of userprofile/models.py and vice versa, it would be nice to show the complete code of the models.

If what you are trying to do is use it for ForeignKey s, you can comment the import lines and use the textual notation. For example:

# from rbsessions.models import Session

class MiModelo(models.Model):
    session = models.ForeignKey('rbsessions.Session')

Update

Do not make problems, what I would do in your case is to pass everything to textual notation for fields that are foreign keys, so you avoid problems with imports:

# rbsessions/models.py

# from userprofile.models import MedicalProfile,TherapistProfile, PatientProfile

class Session(models.Model):
    # ...
    medical = models.ForeignKey('userprofile.MedicalProfile')
    patient = models.ForeignKey('userprofile.PatientProfile')
    therapist = models.ForeignKey('userprofile.TherapistProfile')

# userprofile/models.py

# from rbsessions.models import Session

class MiModelo(models.Model):
    # ...
    session = models.ForeignKey('rbsessions.Session')

With this, in your models.py files you should no longer have from app.models import X anywhere.

    
answered by 20.01.2016 / 17:14
source