我正在将应用程序从 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)**
Run Code Online (Sandbox Code Playgroud)
我的模型是:
身份验证/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
Run Code Online (Sandbox Code Playgroud)
企业 / 模特 / __init__.py
...
from .section import Section
...
Run Code Online (Sandbox Code Playgroud)
企业/模型/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, ...)
...
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
ris*_*rri 51
对于未来的读者,如果您将 python 文件命名为与项目使用的依赖项相同的名称,也会发生这种情况。
例如:
我不能有一个名为 retrying.py 的文件正在使用重试包。
假设我的项目中有重试包,我不能有一个名为 retrying.py 的文件,其中包含以下内容:
from retrying import retry
print("HI")
Run Code Online (Sandbox Code Playgroud)
会出现类似的错误消息“很可能是由于循环导入”。
如果我将文件重命名为“retrying_example1.py”,相同的内容将正常工作
Lon*_*ami 13
从其他文件导入代码时,如果您详细说明要导入的内容来自的整个子包,则会有所帮助。假设您有以下文件结构:
mypackage/
subpackage/
__init__.py
helper.py
main/
work.py
Run Code Online (Sandbox Code Playgroud)
如果:
__init__.py从以下位置导入内容helper.py(以便最终用户方便地访问)work.pysubpackage/helper.py然后而不是这样做:
mypackage/
subpackage/
__init__.py
helper.py
main/
work.py
Run Code Online (Sandbox Code Playgroud)
你应该这样做:
from ..subpackage import thing_i_need
Run Code Online (Sandbox Code Playgroud)
对于合理的代码,这应该可以帮助您避免一些循环依赖问题,因为现在您不再依赖于__init__.py完全完成。
你有一个循环导入。
authentication/models 导入公司/模型,导入公司/模型/部分,导入身份验证/模型。
你不能那样做。
当我尝试进行相对导入时收到此错误。我有两个模型文件:
utils.models:
class BaseModel(models.Model):
...
Run Code Online (Sandbox Code Playgroud)
main.models:
from .models import BaseModel
...
Run Code Online (Sandbox Code Playgroud)
当main.models我将其更改为:
from utils.models import BaseModel
Run Code Online (Sandbox Code Playgroud)
进口事项的顺序__init__.py:
模型/init.py
from .a import A
from .b import B
Run Code Online (Sandbox Code Playgroud)
a.py
from models.b import B
...
Run Code Online (Sandbox Code Playgroud)
这将给ImportError: cannot import name 'B' from partially initialized module 'models' (most likely due to a circular import) (/models/__init__.py)
要解决此问题,应先导入 in,B再导入Ain__init__.py
| 归档时间: |
|
| 查看次数: |
41802 次 |
| 最近记录: |