使用Django管理命令的Python导入问题

时间:2010-09-14 18:36:02

标签: python django import

无论出于何种原因,当我不熟悉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

这是设置循环导入类型的情况吗?

3 个答案:

答案 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命令,很难确切地说明发生了什么。但是,在循环导入的情况下,我经常看到“没有属性”,并且几乎总是通过将模块级导入更改为函数级或类级导入来修复,就像在此处所做的那样。你可能会检查这里是否有类似的东西。