无论出于何种原因,当我不熟悉Python和Django时,我在models.py文件的顶部写了一些这样的import语句:
from django.contrib import auth
我会像这样使用它:
class MyModel(models.Model):
user = models.ForeignKey(auth.models.User)
# ...
这很好用。很久以后,我写了一个自定义管理命令,它会这样做:
from myapp.models import MyModel
当我运行自定义命令(python manage.py my_command
)时,这会导致Python抱怨模块auth
在模型中声明models
的行上没有属性ForeignKey
的.py。
要解决此问题,我将models.py更改为更常见的:
from django.contrib.auth.models import User
class MyModel(models.Model):
user = models.ForeignKey(User)
# ...
有人可以向我解释我错过了什么吗?运行管理命令时,环境中是否存在不同之处?或者我一直都做错了?谢谢!
编辑:在dmitko关于循环导入的预感之后,以下是我的models.py文件中使用的导入。我正在显示auth
的原始导入,以及唯一具有auth用户模型外键的模型:
import datetime
from django.db import models
# from django.contrib import auth
from django.contrib.auth.models import User
class UserLastVisit(models.Model):
# user = models.ForeignKey(auth.models.User, unique=True)
# ^^^^^^^^^^^^^^^^
# after adding mgmt command, error occurred here; change to the line below
user = models.ForeignKey(User, unique=True)
last_visit = models.DateTimeField(db_index=True)
以下是发现问题的管理命令的导入:
import datetime
from django.core.management.base import NoArgsCommand
from core.models import UserLastVisit, AnonLastVisit, Statistic
这是设置循环导入类型的情况吗?
答案 0 :(得分:5)
如果某个随机模块导入模块x.y.z
,那么后来只导入x.y
的人会在z
命名空间中看到x.y
。
发生这种情况的原因是import x.y.z
实际上是一个中的三个import语句。它的工作原理如下:
x = __internal_import('x')
x.y = __internal_import('x/y')
x.y.z = __internal_import('x/y/z')
下次有人__internal_import('x/y')
时,他们会获得相同的对象,因为python足够智能,不会导入两次相同的对象。该对象已将z
成员分配给z
模块。
在您的完整应用中,您可能拥有一个import django.contrib.auth.models
的模块。但是您的最小独立程序没有导入该模块,因此从未分配过该名称。
(注意:没有__internal_import
这样的东西。这只是一个例子。真正的函数有一些你必须查找的其他名称。)
答案 1 :(得分:0)
我想如果你做from django.contrib import auth
这意味着你将auth软件包导入为模块,它导出的内容由auth文件夹中的__init__.py
驱动:
>>> from django.contrib import auth
>>> dir(auth)
['BACKEND_SESSION_KEY', 'ImproperlyConfigured', 'REDIRECT_FIELD_NAME', 'SESSION_
KEY', '__builtins__', '__doc__', '__file__', '__name__', '__path__', 'authentica
te', 'datetime', 'get_backends', 'get_user', 'import_module', 'load_backend', 'l
ogin', 'logout']
您可以查看__init__.py
中的django\contrib\auth
并查看相同的功能列表。当您导入from django.contrib.auth.models import User
时,这意味着您正在从auth
包中导入子模块并且它可以正常工作。
顺便说一句。在任何情况下我都无法使用auth.models.User
- 无论是从控制台还是从我的django应用程序运行。
答案 2 :(得分:0)
如果没有看到您添加的新manage.py命令,很难确切地说明发生了什么。但是,在循环导入的情况下,我经常看到“没有属性”,并且几乎总是通过将模块级导入更改为函数级或类级导入来修复,就像在此处所做的那样。你可能会检查这里是否有类似的东西。