我的views.py
变得太大了,很难找到正确的观点。
如何将其拆分为多个文件然后导入?它是否涉及任何速度损失?
我可以对models.py
执行相同的操作吗?
答案 0 :(得分:170)
在Django中,一切都是Python模块(* .py)。您可以在里面创建一个__init__.py
的视图文件夹,但您仍然可以导入视图,因为这也实现了一个Python模块。但是一个例子会更好。
您的原始views.py
可能如下所示:
def view1(arg):
pass
def view2(arg):
pass
使用以下文件夹/文件结构,它将起作用:
views/
__init__.py
viewsa.py
viewsb.py
viewsa.py
:
def view1(arg):
pass
viewsb.py
:
def view2(arg):
pass
__init__.py
:
from viewsa import view1
from viewsb import view2
快速解释是:当您编写from views import view1
时,Python会在
views.py
,这是第一个(原始)案例中发生的事情
views/__init__.py
,这是第二种情况。在这里,__init__.py
能够提供view1方法,因为它会导入它。
使用此类解决方案,您可能无需在import
urlpattern
或urls.py
个参数
如果每个新视图文件中有多个方法,您可能会发现在views/__init__.py
中使用*
进行导入很有用,如下所示:
from viewsa import *
from viewsb import *
我实际上不知道速度问题(但我怀疑有没有)。
对于模型,它可能有点困难。
答案 1 :(得分:20)
我之前必须这样做(为了清楚起见)
我这样做的方法是创建一个views
目录,然后在其中创建一个名为__init__.py
的文件
现在,当您使用urls.py
进行呼叫时,只需添加其他部分
例如,之前您可能会调用: -
url(r'^calendar/(?P<year>\d\d\d\d)/$', 'myproject.calendar.views.year')
url(r'^calendar/(?P<year>\d\d\d\d)/(?P<user>[a-z]+)/$', 'myproject.calendar.views.year_by_user')
您现在可以按照
的方式调用某些内容url(r'^calendar/(?P<year>\d\d\d\d)/$', 'myproject.calendar.views.year.index')
url(r'^calendar/(?P<year>\d\d\d\d)/(?P<user>[a-z]+)/$', 'myproject.calendar.views.year.user')
当然,这是假设您views/year.py
包含函数index
和user
;)
答案 2 :(得分:9)
基本上,您可以随意放置代码。只需确保,您可以相应地更改导入语句,例如对于urls.py
中的观点。
不知道你的实际代码很难建议有意义的东西。也许你可以使用某种文件名前缀,例如views_helper.py
,views_fancy.py
,views_that_are_not_so_often_used.py
左右......
另一种选择是使用views
创建__init__.py
目录,您可以在其中导入所有子视图。如果您需要大量文件,则可以在视图增长时创建更多嵌套子视图...
答案 3 :(得分:6)
仅仅为了分享,我对Vincent Demeester的回答有些疑问。一切都很好,除了 init .py文件,我必须这样写:
<强> __初始化__吡啶强>:
from .viewsa import *
from .viewsb import *
这样我仍然不需要在urls.py中更改我的import
方法。我在 Python 3.6.1 和 Django 1.11.4 。
答案 4 :(得分:5)
简单回答:是的。
最好是创建一个名为views的目录,然后在你的urls.py中执行:
import views
...
url(r'^classroom$', views.school.klass, name="classroom"),
答案 5 :(得分:1)
由于Django只希望视图是一个可调用的对象,所以你可以在PYTHONPATH中放置任何你喜欢的地方。因此,您可以例如创建一个新的包myapp.views并将视图放入多个模块中。您自然需要更新urls.py以及引用这些视图callables的其他模块。
答案 6 :(得分:1)
我将应用中的几乎所有视图分成了一个视图文件夹(当然还有 init .py)。但是,我不会像 init .py那样导入所有子视图,就像一些答案所建议的那样。它似乎工作得很好。
答案 7 :(得分:1)
我一直在玩这个 init .py:
import os
currPath = os.path.realpath(os.path.dirname(__file__))
dirFiles = []
for root, dirs, files in os.walk(currPath):
for name in files:
if name.endswith('.py') and not name.startswith('_'):
dirFiles.append(name.strip('.py'))
for f in dirFiles:
exec("from %s import %s" % (f,f))
我还是python的新手,所以我仍然在研究它对速度/安全性/易用性的影响。
答案 8 :(得分:1)
假设您有一个名为password_generator.py
的文件,则在views.py
内添加:from password_generator import *
然后你可以从views.py
调用该模块的功能。
答案 9 :(得分:1)
Vincent Demeester的答案非常棒!但对我来说,addicted的答案就像一个魅力。 我在迁移数据库时遇到困难。该错误指示导入了第一个模型的行,并指出无法识别我的应用程序模块。搜索了很多但找不到解决方案,但是后来我像这样导入了模型:
list_numbers={}
ratio1 = 1
ratio2 = 3698
for x in range(1,100):
list_numbers.update({ratio1*x: ratio2*x})
成功了!