2010-09-14 31 views
4

無論出於何種原因,當我是新來的Python和Django的,我寫了一些import語句像這樣在models.py文件的頂部:使用Django管理Python的導入問題命令

from django.contrib import auth 

而且我d使用它是這樣的:

class MyModel(models.Model): 
    user = models.ForeignKey(auth.models.User) 
    # ... 

這工作正常。時間長了以後,我寫了一個自定義的管理命令,它會做到這一點:

from myapp.models import MyModel 

當我跑我的自定義命令(),這將導致在Python抱怨模塊auth沒有屬性models上在models.py中聲明ForeignKey

要解決這個問題,我改變了我的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 

這是否設置了循環導入類型的情況?

回答

5

如果一些隨機模塊以往進口模塊x.y.z,那麼誰進口只是x.y會看到x.y命名空間z以後的人。

發生這種情況的原因是import x.y.z實際上是三個導入語句之一。它的工作原理是這樣的:

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沒有這樣的事情這只是一個例證真正的函數,你將不得不尋找一些其他的名字)

+0

太棒了,謝謝你的解釋。 – 2010-09-16 23:44:36

0

我想,如果你做from django.contrib import 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'] 

您可以django\contrib\auth檢查__init__.py看相同的功能列表。當您導入from django.contrib.auth.models import User這意味着您要從auth包中導入子模塊並且它可以工作。

順便說一句。無論如何,我無法使用auth.models.User - 無論是從控制檯還是從我的django應用程序運行。

+0

嗯。感謝您的回覆,我會更多地研究這一點。不過,我希望我能解釋爲什麼在編寫管理命令之前使用'auth.models.User'爲我工作。 – 2010-09-15 13:40:46

0

如果沒有看到您添加的新manage.py命令,很難確切地說出發生了什麼。但是,在循環導入的情況下,我經常會看到「沒有屬性」,並且幾乎總是通過將模塊級導入更改爲函數級或類級導入來修復,就像您在此處所做的那樣。你可能會檢查是否有類似的事情發生在這裏。

+0

我編輯了我的問題,顯示了我希望的代碼的相關部分。我不認爲有一個循環進口,但你有什麼可疑的? – 2010-09-16 12:53:30