在几个文件中拆分views.py
Posted
技术标签:
【中文标题】在几个文件中拆分views.py【英文标题】:Split views.py in several files 【发布时间】:2010-12-27 15:57:20 【问题描述】:我的views.py
太大了,很难找到合适的视图。
如何将其拆分为多个文件然后导入?是否涉及速度损失?
我可以对models.py
做同样的事情吗?
【问题讨论】:
我将我的大型(7k 行)views.py 文件拆分为单独的文件,速度的提升非常显着。 【参考方案1】:基本上,您可以随意放置代码。只要确保您相应地更改导入语句,例如对于urls.py
中的意见。
不知道你的实际代码很难提出有意义的建议。也许您可以使用某种文件名前缀,例如views_helper.py
、views_fancy.py
、views_that_are_not_so_often_used.py
左右……
另一种选择是创建一个带有__init__.py
的views
目录,您可以在其中导入所有子视图。如果您需要大量文件,您可以随着视图的增长创建更多的嵌套子视图...
【讨论】:
【参考方案2】:在 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 方法,因为它导入了它。
使用这种解决方案,您可能无需更改 urls.py
中的 import
或 urlpattern
s 参数
如果您在每个新视图文件中都有很多方法,您可能会发现将 views/__init__.py
中的导入使用 *
很有用,如下所示:
from viewsa import *
from viewsb import *
我实际上不知道速度问题(但我怀疑是否存在)。
对于模型来说,这可能有点困难。
【讨论】:
能否在您的示例中添加与 view1 或 view2 匹配的 url 模式?因为我有这个问题.... 我试过这样做,但是当我去导入我的模型时(从 app.models 导入 MyModel 或从模型导入 MyModel)Python 抱怨模型不存在。 删除根目录下的views.py可以吗? 这个解决方案对我不起作用(与@ChrisMiller 的错误相同。我的解决方案:在__init__.py
:from myapp.views.viewsa import *
。请注意,您不能再拥有views.py(或至少它不会被读取 @ShiftNTab: Error for not found your views in views.py)。希望对您有所帮助!
我必须使用句点:from .viewsa import * -- 如果这是一个普遍的问题/解决方案,可能值得更正答案。【参考方案3】:
由于 Django 只希望视图是可调用对象,因此您可以将其放在 PYTHONPATH 中任何您喜欢的位置。因此,您可以例如创建一个新包 myapp.views 并将视图放入多个模块中。您自然必须更新您的 urls.py 和其他引用这些视图可调用对象的模块。
【讨论】:
这实际上是不正确的——它可以用模型来完成。见:code.djangoproject.com/ticket/4470 啊,很高兴知道,谢谢 :-) 我一直认为模型以及它们如何在应用程序包中存在更多的魔力。在我的回复中删除了关于模型的行。 很高兴我能帮上忙,后来我意识到这个链接实际上解释了如何更好地使用模型:blog.amber.org/2009/01/19/…【参考方案4】:简单的回答:是的。
最好是创建一个名为 views 的目录,然后在你的 urls.py 中做:
import views
...
url(r'^clas-s-room$', views.school.klass, name="clas-s-room"),
【讨论】:
【参考方案5】:我以前必须这样做(为了清楚起见)
我这样做的方法是创建一个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
;)
【讨论】:
【参考方案6】:我将应用程序中的几乎所有视图都拆分到一个视图文件夹中(当然还有一个 init.py)。但是,我不会像某些答案所建议的那样导入 init.py 中的所有子视图。它似乎工作得很好。
【讨论】:
【参考方案7】:我一直在尝试将其放入我的 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】:假设如果您有一个名为:password_generator.py
的文件,那么在 views.py
中添加:from password_generator import *
然后您可以从views.py
调用该模块的函数。
【讨论】:
【参考方案9】:只是为了分享,我对 Vincent Demeester 的回答有些疑问。一切都很好,除了 init.py 文件,我必须这样写:
__init__.py:
from .viewsa import *
from .viewsb import *
这样我仍然不需要在 urls.py 中更改我的 import
方法。我正在使用 Python 3.6.1 和 Django 1.11.4。
【讨论】:
【参考方案10】:Vincent Demeester 的回答太棒了!但对我来说addicted 的回答就像一个魅力。 我在迁移数据库时遇到了困难。该错误指示导入第一个模型的行并说无法识别我的应用程序模块。搜索了很多但找不到解决方案,但后来我导入了这样的模型:
from ..models import ModelName
成功了!!
【讨论】:
以上是关于在几个文件中拆分views.py的主要内容,如果未能解决你的问题,请参考以下文章
Rails ::module_name vs module_name 和模块在几个文件之间拆分
Django:如何从views.py获取字典到javascript函数(html文件)