在几个文件中拆分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.pyviews_fancy.pyviews_that_are_not_so_often_used.py 左右……

另一种选择是创建一个带有__init__.pyviews 目录,您可以在其中导入所有子视图。如果您需要大量文件,您可以随着视图的增长创建更多的嵌套子视图...

【讨论】:

【参考方案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会在

中寻找view1

    views.py,这是第一个(原始)案例中发生的情况

    views/__init__.py,这是在第二种情况下发生的情况。在这里,__init__.py 能够提供 view1 方法,因为它导入了它。

使用这种解决方案,您可能无需更改 urls.py 中的 importurlpatterns 参数

如果您在每个新视图文件中都有很多方法,您可能会发现将 views/__init__.py 中的导入使用 * 很有用,如下所示:

from viewsa import *
from viewsb import *

我实际上不知道速度问题(但我怀疑是否存在)。

对于模型来说,这可能有点困难。

【讨论】:

能否在您的示例中添加与 view1 或 view2 匹配的 url 模式?因为我有这个问题.... 我试过这样做,但是当我去导入我的模型时(从 app.models 导入 MyModel 或从模型导入 MyModel)Python 抱怨模型不存在。 删除根目录下的views.py可以吗? 这个解决方案对我不起作用(与@ChrisMiller 的错误相同。我的解决方案:在__init__.pyfrom 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 包含函数 indexuser ;)

【讨论】:

【参考方案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.1Django 1.11.4

【讨论】:

【参考方案10】:

Vincent Demeester 的回答太棒了!但对我来说addicted 的回答就像一个魅力。 我在迁移数据库时遇到了困难。该错误指示导入第一个模型的行并说无法识别我的应用程序模块。搜索了很多但找不到解决方案,但后来我导入了这样的模型:

from ..models import ModelName

成功了!!

【讨论】:

以上是关于在几个文件中拆分views.py的主要内容,如果未能解决你的问题,请参考以下文章

Rails ::module_name vs module_name 和模块在几个文件之间拆分

Django:在几个页面上“拆分”一个表单

如何从views.py文件将数据插入django数据库?

Django:如何从views.py获取字典到javascript函数(html文件)

如何使用从views.py发送的变量将几个参数传递给url模板标签

views.py文件详解