Django - 从单独的应用程序导入视图

时间:2012-07-11 18:52:14

标签: python django

我是Django的新手,并通过Holovaty和Kaplan-Moss的“The Django Book”工作。我有一个名为“mysite”的项目,其中包含两个名为“books”和“contact”的应用程序。每个都有自己的view.py文件。在我的urls.py文件中,我有以下内容:

from books import views
from contact import views
...
urlpatterns = patterns('',
...
(r'^search/$', views.search),
(r'^contact/$', views.contact),
...

当我运行我的代码时,我收到此错误:

/ search /中的NameError ... 异常值:'module'对象没有属性'search'

我认为正在发生的事情是,由于联系人的观点是最后导入的,因此Django正在查看不包含搜索的联系人视图(搜索在书籍视图中)。

从Django urls文件中的两个不同应用程序导入views.py文件的正确方法是什么?

感谢您的帮助!

5 个答案:

答案 0 :(得分:18)

免责声明:不是Django的回答

问题在于这两行:

from books import views
from contact import views

第二个导入是第一个导入,因此当您稍后使用views时,您只使用views中的contact

一种解决方案可能就是:

import books
import contact

urlpatterns = patterns('',
...
(r'^search/$', books.views.search),
(r'^contact/$', contact.views.contact),
...

我不确定,但我也认为你实际上并不需要导入任何东西,只能在你的模式中使用字符串,例如:'books.views.search'


另一种可能性是遵循Simon Visser建议:

from books.views import search
from contact.views import contact

答案 1 :(得分:6)

from books import views
from contact import views

您正在覆盖名称views。您需要将它们作为不同的名称或绝对名称导入。

import books.views
import contact.views

......或......

from books import views as books_views
from contact import views as contact_views

然后在定义网址时使用正确的名称。 (books.views.searchbooks_views.search取决于您选择的方法)

答案 2 :(得分:2)

URLconfs documentation给出了相同情况的示例

您可以跳过导入并按app分隔网址:

urlpatterns = patterns('books.views',
    (r'^/book/search/$', 'search'), #calls books.views.search
)

urlpatterns += patterns('contact.views', #make note of the '+='
    (r'^/contact/search/$', 'search'), #calls contact.views.search
)

答案 3 :(得分:1)

我回答这个问题的原因是因为它在几年前得到了解答,而且对于较新的Django版本,这些答案不再正确或有用,或者你应该知道更好的做法。

因此,如果您的Django项目中有多个应用程序,那么您应该为每个应用程序使用新的urls.py文件。这意味着如果您启动一个新应用程序,则必须在新应用程序的子文件夹中手动创建一个名为urls.py的新文件。许多初学者首先不明白为什么这是好的,但如果您计划在一个Django项目中创建更多应用程序,这是一个很好的做法。

当你启动一个项目时,urls.py文件会自动在你的项目文件夹中创建,但如果你在Django中创建/启动一个新应用程序,那么如果你为该应用程序创建一个单独的urls.py是一个很好的做法。在自己的文件夹中。 (通过这种方式,您将永远不会有#34;首先将不同应用的视图导入urls.py"问题。)

为您的应用创建urls.py文件后,您必须以下列方式在项目的urls.py文件中包含该应用的urls.py文件:

让我们看一下创建名为“my_new_app”的新应用时的示例。 这是项目的主要urls.py文件的样子:

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^my_new_app/', include('my_new_app.urls')),
]

在项目的urls.py文件中,您必须导入'include'方法,然后您可以在项目的主urls.py文件中包含my_new_app urls.py文件。在my_new_app文件夹中,您必须手动创建urls.py文件,如上所述。然后你必须将该文件用于my_new_app的所有urlpatterns。然后当然这样它将自动包含在项目的主urls.py文件中。

那么这就是你的my_new_app自己的urls.py文件的样子:

from django.conf.urls import url
from my_new_app import views

urlpatterns = [
    url(r'^$', views.index, name = "index"),
]

假设您还在'my_new_app / views.py文件中创建了名为'index'的第一个视图。

my_new_app / views.py文件如下所示:

from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello World!")

您可以在浏览器中查看my_new_app:

http://localhost:8000/my_new_app

(当然,您可以在项目的urls.py文件中为my_new_app提供任何网址。)

现在,您可以在Django项目中创建另一个名为my_second_app的应用程序,您也应该为该应用程序重复上述步骤。这样,将不同应用程序中的视图导入urls.py文件就不会有任何问题。对于2017年Django 1.11中的这个问题,这将是一个非常基本的“良好实践解决方案”。

答案 4 :(得分:0)

在这里,我针对不同的View / API版本采用的方法:

from django.urls import path

from my_app import views as api_v1
from my_app import views_v2 as api_v2

urlpatterns = [
    path('view_one', api_v1.ViewOne.as_view()),
    path('view_two', api_v2.ViewTwo.as_view()),
]