Skip to main content
 首页 » 编程设计

python之django 中的循环导入错误

2024年09月07日41haluo1

我将我的 django 结构组织成一个 views 和 urls 文件夹。 在 /appfolder/urls/_ init _.py 或 url 中的任何地方导入 django.contrib.auth.views.login像这样查看文件夹:

from django.contrib.auth.views import login 

我不断得到:

ImportError: cannot import name login

我认为这与更改后的结构有关。我想像这样将它包含在我的 url 模式中:

path('portal/', login, {'template_name': 'portal/index.html'}) 

如何在不出现循环导入错误的情况下导入登录信息?

目录结构

appfolder 
│    
└─── __init__.py        
└─── admin.py 
└─── apps.py    
└─── forms.py 
└─── models.py          
│ 
└───urls 
│   │   __init__.py     | 
│   │   books_urls.py   | 
|   |   movies_urls.py  | 
|   |   portal_urls.py  | 
│   |_ _ _ _ _ _ _ _ _ _| 
|     
└───views 
│   │   __init__.py      | 
│   │   books_views.py   | 
|   |   movies_views.py  | 
|   |   portal_views.py  | 
│   |_ _ _ _ _ _ _ _ _ _ | 

appfolder/urls/_ init _.py

from django.urls import include 
from django.contrib.staticfiles.urls import staticfiles_urlpatterns 
from django.conf.urls.static import static 
from django.conf import settings 
 
from django.contrib.auth.views import login 
 
from .books_urls import * 
from .movies_urls import * 
from .portal_urls import * 
 
urlpatterns = [ 
    path('accounts/', include('django.contrib.auth.urls')), 
    path('portal/', login, {'template_name': 'portal/index.html'}), 
    path('portal/', include('appfolder.urls.portal_urls')), 
    path('movies/', include('appfolder.urls.movies_urls')), 
    path('books/', include('appfolder.urls.books_urls')), 
] 
 
urlpatterns += staticfiles_urlpatterns() 
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 

堆栈跟踪:

> Unhandled exception in thread started by <function 
> check_errors.<locals>.wrapper at 0x0000013AEBD7D048> Traceback (most 
> recent call last):   File 
> "C:\Users\User\Envs\webshop\lib\site-packages\django\utils\autoreload.py", 
> line 225, in wrapper 
>     fn(*args, **kwargs)   File "C:\Users\User\Envs\webshop\lib\site-packages\django\core\management\commands\runserver.py", 
> line 117, in inner_run 
>     self.check(display_num_errors=True)   File "C:\Users\User\Envs\webshop\lib\site-packages\django\core\management\base.py", 
> line 379, in check 
>     include_deployment_checks=include_deployment_checks,   File "C:\Users\User\Envs\webshop\lib\site-packages\django\core\management\base.py", 
> line 366, in _run_checks 
>     return checks.run_checks(**kwargs)   File "C:\Users\User\Envs\webshop\lib\site-packages\django\core\checks\registry.py", 
> line 71, in run_checks 
>     new_errors = check(app_configs=app_configs)   File "C:\Users\User\Envs\webshop\lib\site-packages\django\core\checks\urls.py", 
> line 40, in check_url_namespaces_unique 
>     all_namespaces = _load_all_namespaces(resolver)   File "C:\Users\User\Envs\webshop\lib\site-packages\django\core\checks\urls.py", 
> line 57, in _load_all_namespaces 
>     url_patterns = getattr(resolver, 'url_patterns', [])   File "C:\Users\User\Envs\webshop\lib\site-packages\django\utils\functional.py", 
> line 37, in __get__ 
>     res = instance.__dict__[self.name] = self.func(instance)   File "C:\Users\User\Envs\webshop\lib\site-packages\django\urls\resolvers.py", 
> line 533, in url_patterns 
>     patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)   File 
> "C:\Users\User\Envs\webshop\lib\site-packages\django\utils\functional.py", 
> line 37, in __get__ 
>     res = instance.__dict__[self.name] = self.func(instance)   File "C:\Users\User\Envs\webshop\lib\site-packages\django\urls\resolvers.py", 
> line 526, in urlconf_module 
>     return import_module(self.urlconf_name)   File "C:\Users\User\Envs\webshop\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 "C:\Users\User\Desktop\project\company\com\com\urls.py", line 10, in 
> <module> 
>     path('', include('appfolder.urls')),   File "C:\Users\User\Envs\webshop\lib\site-packages\django\urls\conf.py", 
> line 34, in include 
>     urlconf_module = import_module(urlconf_module)   File "C:\Users\User\Envs\webshop\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 "C:\Users\User\Desktop\project\company\com\appfolder\urls\__init__.py", 
> line 8, in <module> 
>     from django.contrib.auth.views import login ImportError: cannot import name 'login' 

请您参考如下方法:

你遇到的问题是,虽然

from .portal_urls import * 

只是导入从当前文件目录中找到的 portal_urls.py 中的所有内容,这种类型的导入

import appfolder.urls.portal_urls 

将在加载 appfolder/urls/portal_urls.py 之前同时加载 appfolder/__init__.py 和 appfolder/urls/__init__.py ( [*] 请参阅底部的示例)。

这就是为什么,在您的 appfolder/__init__.py 中,编译器通过了这个导入

... 
from .portal_urls import * 

在被这个噎住之前:

urlpatterns = [ 
    ... 
    path('portal/', include('appfolder.urls.portal_urls')), 

如果您以正常方式构建您的应用程序,则可以避免此问题,即

appfolder 
│   __init__.py 
│   urls.py 
│ 
├───books 
│       __init__.py 
│       urls.py 
│ 
├───movies 
│       __init__.py 
│       urls.py 
│ 
└───portal 
        __init__.py 
        urls.py 

所有 __init__.py 文件都是空的,appfolder/urls.py 包含

urlpatterns = [ 
    ... 
    path(r'^portal/', include('appfolder.portal.urls')), 
    path(r'^movies/', include('appfolder.movies.urls')), 
    path(r'^books/', include('appfolder.books.urls')), 

如果这些文件夹增长,这种结构还可以更轻松地将其中一个文件夹拉出到它自己的模块中。

[*] 如果您将 print(__file__) 放在每个 __init__.py 文件中,您可以检查导入的内容:

(dev) go|c:\srv\tmp> python -c "import appfolder.books.urls" 
appfolder\__init__.py 
appfolder\books\__init__.py