django 导入错误:无法从部分初始化的模块'...'汇入名称'...'(很可能是因为循环汇入)

nwlqm0z1  于 2022-11-18  发布在  Go
关注(0)|答案(7)|浏览(263)

我 正在 将 一 个 应用 程序 从 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)**

中 的 每 一 个
我 的 模特 是 :

authentication / 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
...

格式

corporate / models / 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, ...)
    ...

格式
我 做 错 了 什么 ?

fhg3lkii

fhg3lkii1#

对于未来的读者来说,如果将python文件命名为与项目使用的依赖项相同的名称,也可能发生这种情况。
例如:
我不能让名为www.example.com的文件retrying.py使用重试软件包。
假设我的项目中有retrying包,我不能有一个名为www.example.com的文件retrying.py,它包含以下内容:

from retrying import retry
print("HI")

也会出现类似的错误消息“很可能是由于循环导入”。
如果我将文件重命名为“retrying_example1.py”,同样的内容也可以正常工作。

yr9zkbsy

yr9zkbsy2#

您有一个循环导入。
authentication/models导入corporate/modelscorporate/models导入corporate/models/sectioncorporate/models/section导入authentication/models
你不能这么做

gudnpqoy

gudnpqoy3#

当从其他文件导入代码时,如果你拼写出 * 整个 * 子包,你想导入的代码来自哪个子包,这会很有帮助。假设你有以下文件结构:

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来完全完成。

nfzehxib

nfzehxib4#

当我尝试进行相对导入时收到此错误。我有两个模型文件:
utils.models

class BaseModel(models.Model):
    ...

main.models

from .models import BaseModel
...

main.models中,我将其更改为以下内容时,该问题已得到修复:

from utils.models import BaseModel
mnowg1ta

mnowg1ta5#

在我的例子中,问题是我在x.py文件和x.py文件中定义了函数,我从www.example.com文件导入了模型modals.py,在modals.py文件中,我尝试导入此函数,我尝试在使用此函数查询表后设置默认值

kiz8lqtg

kiz8lqtg6#

解决循环导入的一种方法是将循环中的一个文件拆分为多个文件,这样这些文件就不再相互导入了。在这个特定的例子中,我 * 认为 * 如果将get_sentinel移到一个单独的文件中,这个问题就可以解决了。

身份验证/模型实用程序.py

def get_sentinel():
    ...

公司/型号/section.py

from django.conf import settings
from authentication.models_utils import get_sentinel
from .room import Room

class Section(models.Model):
...
r6hnlfcb

r6hnlfcb7#

我得到了下面相同的错误:
属性错误:部分初始化的模块'math'没有属性'pi'(很可能是因为循环汇入)
因为我将我的python文件命名为**math.py,导入python的math模块并使用math.pi**,如下所示:

# "math.py"

import math

print(math.pi)

因此,我将**math.py更改为my_math.py**,然后解决了错误。

3.141592653589793

相关问题