【问题标题】:ImportError: cannot import name '...' from partially initialized module '...' (most likely due to a circular import)ImportError:无法从部分初始化的模块“...”导入名称“...”(很可能是由于循环导入)
【发布时间】:2021-02-24 15:35:39
【问题描述】:

我正在将应用程序从 Django 1.11.25 (Python 2.6) 升级到 Django 3.1.3 (Python 3.8.5),当我运行 manage.py makemigrations 时,我收到以下消息:

  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)**

我的模型是:

身份验证/models.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

企业/模特/__init__.py

...
from .section import Section
...

企业/模型/section.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, ...)
    ...

我做错了什么?

【问题讨论】:

  • 更新问题以在 authentication/models.py 的顶部显示导入。
  • 现在你已经得到了你做错的答案,这里有一些实际的帮助:使用from module import *(在某些情况下)。
  • 如果您的文件名与您连接的包名相同,则可能会发生此错误。只需重命名您的文件,它就可以工作。

标签: python django


【解决方案1】:

对于未来的读者,如果您将 python 文件命名为与项目使用的依赖项相同的名称,也会发生这种情况。

例如:

我不能有一个名为 retrying.py 的文件正在使用重试包。

假设我的项目中有重试包,我不能有一个名为 retrying.py 的文件,其内容如下:

from retrying import retry
print("HI")

会出现类似的错误消息“很可能是由于循环导入”。

如果我将文件重命名为“retrying_example1.py”,相同的内容会正常工作

【讨论】:

    【解决方案2】:

    你有一个循环导入。

    authentication/models 导入 corporate/models,后者导入 corporate/models/section,其中 imports authentication/models

    你不能这样做。

    【讨论】:

    • 我的意思是是的。你不能那样做。但了解如何解决它可能会有用。
    • 抱歉,这应该怎么用?
    • 只需更改文件名。例如。你不能有 ray.py 并将 ray 作为一个包导入。
    【解决方案3】:

    当从其他文件导入代码时,如果你拼出整个你想要导入的东西的子包,它会有所帮助。假设您有以下文件结构:

    mypackage/
      subpackage/
        __init__.py
        helper.py
      main/
        work.py
    

    如果:

    • __init__.pyhelper.py 导入东西(方便最终用户访问)
    • 你在里面工作work.py
    • 你需要来自subpackage/helper.py的东西

    然后,而不是做:

    from ..subpackage import thing_i_need
    

    你应该这样做:

    from ..subpackage.helper import thing_i_need
    

    对于合理的代码,这应该可以帮助您避免一些循环依赖问题,因为现在您不再依赖 __init__.py 来完全完成。

    【讨论】:

      【解决方案4】:

      更改工作文件的文件名可以解决我的问题。用于 fbprophet 循环导入。

      【讨论】:

      【解决方案5】:

      在我的情况下,问题是我在 x.py 文件中定义了函数,在 x.py 文件中我从 modals.py 文件中导入模型,在 modals.py 文件中我尝试导入这个函数使用此函数查询表后尝试设置默认值

      【讨论】:

        猜你喜欢
        • 2022-06-22
        • 2022-01-08
        • 2020-05-20
        • 2021-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-12
        • 2021-09-22
        相关资源
        最近更新 更多