我有一个post_save信号,它在另一个应用程序的单独模型中创建一个对象,该应用程序引用当前应用程序中的模型,并且它给出了导入错误。
这是信号
from passwordfolders.models import PasswordFolder
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_personal_list(instance=None, created=False):
if created:
PasswordFolder.objects.create(name='Personal',
description='Personal Folder',
owner=instance,
personal=True,
parent='')
这里是追溯:
Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x0000000004187158>
Traceback (most recent call last):
File "D:\Python36\lib\site-packages\django\utils\autoreload.py", line 225, in wrapper
fn(*args, **kwargs)
File "D:\Python36\lib\site-packages\django\core\management\commands\runserver.py", line 112, in inner_run
autoreload.raise_last_exception()
File "D:\Python36\lib\site-packages\django\utils\autoreload.py", line 248, in raise_last_exception
raise _exception[1]
File "D:\Python36\lib\site-packages\django\core\management\__init__.py", line 327, in execute
autoreload.check_errors(django.setup)()
File "D:\Python36\lib\site-packages\django\utils\autoreload.py", line 225, in wrapper
fn(*args, **kwargs)
File "D:\Python36\lib\site-packages\django\__init__.py", line 24, in setup
apps.populate(settings.INSTALLED_APPS)
File "D:\Python36\lib\site-packages\django\apps\registry.py", line 112, in populate
app_config.import_models()
File "D:\Python36\lib\site-packages\django\apps\config.py", line 198, in import_models
self.models_module = import_module(models_module_name)
File "D:\Python36\lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "D:\Projects\enterpass\api\core\models.py", line 10, in <module>
from passwordfolders.models import PasswordFolder
File "D:\Projects\enterpass\api\passwordfolders\models.py", line 2, in <module>
from core.models import AccessLevel, Owner, User
ImportError: cannot import name 'AccessLevel'
逻辑流程是core
应用中的BaseAbstractUser模型上的post_save,它在PasswordFolder
应用中调用passwordfolders
,其中有AccessLevel
FK引用{{1}在core
应用中。}在尝试引用AccessLevel
上的导入时失败了,这显然存在,所以我不确定它为什么会失败。
core.models:
from django.db import models
from django.db.models.signals import pre_delete, post_delete, pre_save, post_save
from django.conf import settings
from django.dispatch import receiver
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.base_user import AbstractBaseUser
from uuid import uuid4
from .managers import UserManager
from passwordfolders.models import PasswordFolder
class AccessLevel(models.Model):
name = models.CharField(max_length=100)
description = models.CharField(max_length=1024)
class Meta:
db_table = 'auth_accesslevel'
managed = True
def __str__(self):
return self.name
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_personal_list(instance=None, created=False):
if created:
PasswordFolder.objects.create(name='Personal',
description='Personal Folder',
owner=instance,
personal=True,
parent='')
class User(AbstractBaseUser, PermissionsMixin):
is_superuser = models.BooleanField(default=False, editable=True)
is_support = models.BooleanField(default=False, editable=True)
is_servicedesk = models.BooleanField(default=False, editable=True)
is_infosec = models.BooleanField(default=False, editable=True)
is_application = models.BooleanField(default=False, editable=True)
username = models.CharField(max_length=256, unique=True)
first_name = models.CharField(max_length=256)
last_name = models.CharField(max_length=256)
email = models.EmailField(unique=True)
is_active = models.BooleanField(default=True, editable=True)
last_login = models.DateField(auto_now=True)
date_joined = models.DateField(auto_now=True)
uuid = models.UUIDField(default=uuid4, editable=False, unique=True)
def has_perm(self, perm, obj=None):
return self.is_support
def has_module_perms(self, app_label):
return self.is_support
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']
@property
def is_staff(self):
return self.is_support
class Meta:
db_table = 'auth_user'
managed = True
verbose_name = 'user'
verbose_name_plural = 'users'
passwordfolders.models:
from django.db import models
from core.models import AccessLevel, Owner, User
from mptt.models import MPTTModel, TreeForeignKey
from taggit.managers import TaggableManager
from uuid import uuid4
class PasswordFolder(MPTTModel):
name = models.CharField(max_length=100, null=True)
description = models.CharField(max_length=1024)
owner = models.ForeignKey(Owner, null=False, blank=False, default=1, on_delete=models.PROTECT)
personal = models.BooleanField(default=False, null=False)
parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True, on_delete=models.DO_NOTHING)
tags = TaggableManager(blank=True)
created = models.DateTimeField(auto_now_add=True, blank=False)
modified = models.DateTimeField(auto_now=True, blank=True)
class MPTTMEta:
order_insertion_by = ['name']
class Meta:
db_table = 'enterpass_passwordfolder'
managed = True
def __str__(self):
return self.name
class PasswordFolderACL(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT)
folder = models.ForeignKey(PasswordFolder, on_delete=models.PROTECT)
level = models.ForeignKey(AccessLevel, on_delete=models.PROTECT)
key = models.UUIDField(default=uuid4, unique=True)
modified = models.DateTimeField(auto_now=True, blank=False)
class Meta:
db_table = 'enterpass_passwordfolderacl'
managed = True