3WZ
Estoy actualizando una aplicación de Django 1.11.25 (Python 2.6) a Django 3.1.3 (Python 3.8.5) y, cuando ejecuto manage.py makemigrations
recibo este mensaje:
File "/home/eduardo/projdevs/upgrade-intra/corporate/models/section.py", line 9, in <module>
from authentication.models import get_sentinel**
ImportError: cannot import name 'get_sentinel' from partially initialized module 'authentication.models' (most likely due to a circular import) (/home/eduardo/projdevs/upgrade-intra/authentication/models.py)**
Mis modelos son:
autenticación / modelos.py
from django.conf import settings
from django.contrib.auth.models import AbstractUser, UserManager
from django.db import models
from django.db.models.signals import post_save
from django.utils import timezone
from corporate.constants import GROUP_SUPPORT
from corporate.models import Phone, Room, Section
from library.exceptions import ErrorMessage
from library.model import update_through_dict
from .constants import INTERNAL_USER, EXTERNAL_USER, SENTINEL_USERNAME, SPECIAL_USER, USER_TYPES_DICT
class UserProfile(models.Model):
user = models.OneToOneField(
'User',
on_delete=models.CASCADE,
unique=True,
db_index=True
)
...
phone = models.ForeignKey('corporate.Phone', on_delete=models.SET_NULL, ...)
room = models.ForeignKey('corporate.Room', on_delete=models.SET_NULL, ...)
section = models.ForeignKey('corporate.Section', on_delete=models.SET_NULL, ...)
objects = models.Manager()
...
class CustomUserManager(UserManager):
def __init__(self, type=None):
super(CustomUserManager, self).__init__()
self.type = type
def get_queryset(self):
qs = super(CustomUserManager, self).get_queryset()
if self.type:
qs = qs.filter(type=self.type).order_by('first_name', 'last_name')
return qs
def get_this_types(self, types):
qs = super(CustomUserManager, self).get_queryset()
qs = qs.filter(type__in=types).order_by('first_name', 'last_name')
return qs
def get_all_excluding(self, types):
qs = super(CustomUserManager, self).get_queryset()
qs = qs.filter(~models.Q(type__in=types)).order_by('first_name', 'last_name')
return qs
class User(AbstractUser):
type = models.PositiveIntegerField('...', default=SPECIAL_USER)
username = models.CharField('...', max_length=256, unique=True)
first_name = models.CharField('...', max_length=40, blank=True)
last_name = models.CharField('...', max_length=80, blank=True)
date_joined = models.DateTimeField('...', default=timezone.now)
previous_login = models.DateTimeField('...', default=timezone.now)
objects = CustomUserManager()
...
def get_profile(self):
if self.type == INTERNAL_USER:
...
return None
def get_or_create_profile(self):
profile = self.get_profile()
if not profile and self.type == INTERNAL_USER:
...
return profile
def update(self, changes):
...
class ExternalUserProxy(User):
objects = CustomUserManager(type=EXTERNAL_USER)
class Meta:
proxy = True
verbose_name="..."
verbose_name_plural="..."
class InternalUserProxy(User):
objects = CustomUserManager(type=INTERNAL_USER)
class Meta:
proxy = True
verbose_name="..."
verbose_name_plural="..."
def create_profile(sender, instance, created, **kwargs):
if created and instance.type == INTERNAL_USER:
try:
profile = UserProfile()
profile.user = instance
profile.save()
except:
pass
post_save.connect(create_profile, sender=User)
def get_sentinel():
try:
sentinel = User.objects.get(username__exact=SENTINEL_USERNAME)
except User.DoesNotExist:
settings.LOGGER.error("...")
from django.contrib.auth.models import Group
sentinel = User()
sentinel.username = SENTINEL_USERNAME
sentinel.first_name = "..."
sentinel.last_name = "..."
sentinel.set_unusable_password()
sentinel.save()
technical = Group.objects.get(name=GROUP_SUPPORT)
sentinel = User.objects.get(username__exact=SENTINEL_USERNAME)
sentinel.groups.add(technical)
sentinel.save()
return sentinel
corporativo / modelos / __init__.py
...
from .section import Section
...
corporativo / modelos / seccion.py
from django.conf import settings
from authentication.models import get_sentinel
from .room import Room
class Section(models.Model):
...
boss = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET(get_sentinel), ...)
surrogate = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET(get_sentinel), ...)
room = models.ForeignKey(Room, on_delete=models.SET_NULL, ...)
is_subordinate_to = models.ForeignKey('self', on_delete=models.SET_NULL, ...)
...
¿Qué estoy haciendo mal?
Para futuros lectores, esto también puede suceder si nombra un archivo de python con el mismo nombre que una dependencia que usa su proyecto.
Por ejemplo:
No puedo tener un archivo llamado retrying.py que esté usando el paquete de reintento.
Suponiendo que tuviera el paquete de reintento en mi proyecto, no podría tener un archivo llamado retrying.py con el siguiente contenido:
from retrying import retry
print("HI")
Se produciría un error similar con el mensaje “lo más probable es que se deba a una importación circular”.
El mismo contenido funcionaría bien si cambiara el nombre del archivo a “reintentar_ejemplo1.py”
-
¡Gracias, esto resolvió mi problema! Tenía un archivo llamado “token.py”, y solo después de cambiarle el nombre a “generate-token.py”, pude ejecutarlo correctamente.
–Leonardo Gómez
13 de mayo a las 16:08
-
@LeonardoGomes Es gracioso que digas esto. Nombré mi archivo exactamente como “token.py” y me metí en este problema 🙂
– dobladillo
28 de junio a las 2:17
-
¡Me alegro de haberte podido ayudar!
– rishikarri
29 de junio a las 1:14
Juan Gordon
Tienes una importación circular.
authentication/models
importaciones corporate/models
que importa corporate/models/section
cual imports authentication/models
.
No puedes hacer eso.
-
Quiero decir, sí. No puedes hacer eso. Pero algún sentido de cómo abordarlo podría ser útil.
– thms
30 de junio de 2021 a las 16:34
-
simplemente cambie el nombre de su archivo. P.ej. no puede tener ray.py e importar ray como un paquete.
– Jonathan
13 de septiembre de 2021 a las 12:06
Al importar código de otros archivos, ayuda si deletrea la totalidad subpaquete de donde proviene lo que desea importar. Digamos que tiene la siguiente estructura de archivos:
mypackage/
subpackage/
__init__.py
helper.py
main/
work.py
Si:
__init__.py
importa cosas dehelper.py
(para que el usuario final acceda cómodamente)- y tu estas trabajando adentro
work.py
- y necesitas algo de
subpackage/helper.py
Entonces en lugar de hacer:
from ..subpackage import thing_i_need
En su lugar, debe hacer:
from ..subpackage.helper import thing_i_need
Para un código razonable, esto debería ayudarlo a evitar algunos de los problemas de dependencia circular, ya que ahora ya no depende de __init__.py
para terminar por completo.
Recibí este error cuando intenté hacer una importación relativa. Tenía dos archivos de modelos:
utils.models
:
class BaseModel(models.Model):
...
main.models
:
from .models import BaseModel
...
El problema se solucionó cuando, en main.models
lo cambié a:
from utils.models import BaseModel
En mi caso el problema fue que definí la función en el archivo x.py y en el archivo x.py importo modelos del archivo modals.py y en el archivo modals.py traté de importar esta función que estaba tratando de establezca el valor predeterminado después de consultar las tablas con esta función
Actualice la pregunta para mostrar las importaciones en la parte superior de
authentication/models.py
.– John Gordon
12 de noviembre de 2020 a las 15:52
Ahora que obtuviste la respuesta de lo que hiciste mal, aquí hay algo de ayuda real: Usa
from module import *
(en algunos casos).– usuario136036
4 de marzo de 2021 a las 21:42
Este error puede ocurrir en caso de que el nombre de su archivo sea el mismo que el nombre del paquete que conecta. Simplemente cambie el nombre de su archivo y funcionará.
– zorro astuto
18/09/2021 a las 15:33
¿Responde esto a tu pregunta? no se puede importar el nombre ‘mydb’ del módulo ‘conexión’ parcialmente inicializado en Python
– Marca
11 de febrero a las 17:35
Realmente no entendía cuál era el problema, así que usé el otro modelos.py desde donde importé modelos e hice el modelo allí y funcionó.
– Usuario anónimo
17 de agosto a las 5:23