将views.py拆分为多个文件

问题描述 投票:0回答:11

我的

views.py
变得太大了,很难找到合适的视图。

如何将其拆分为多个文件然后导入?是否会造成速度损失?

我可以对

models.py
做同样的事情吗?

python django
11个回答
233
投票

在 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
  1. views.py
    ,这就是第一种(原始)情况下发生的情况

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

使用这种解决方案,您可能不需要更改

import
 中的 
urlpattern
urls.py

的参数

如果每个新视图文件中有许多方法,您可能会发现在

views/__init__.py
中使用
*
进行导入很有用,如下所示:

from viewsa import *
from viewsb import *

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

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


24
投票

我以前必须这样做(为了清楚起见)

我这样做的方法是创建一个

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
;)


17
投票

仅供分享,我对 Vincent Demeester 的回答有一些疑问。一切都很好,除了在 init.py 文件中,我必须这样写:

__init__.py:

from .viewsa import *
from .viewsb import *

这样我仍然不需要更改 urls.py 中的

import
方法。我使用的是 Python 3.6.1Django 1.11.4


11
投票

基本上,您可以将代码放在您希望的任何位置。只需确保相应地更改导入语句,例如查看

urls.py
中的视图。

不知道你的实际代码很难提出有意义的建议。也许您可以使用某种文件名前缀,例如

views_helper.py
views_fancy.py
views_that_are_not_so_often_used.py
左右...

另一种选择是创建一个带有

views
__init__.py
目录,您可以在其中导入所有 子视图。如果您需要大量文件,您可以随着视图的增长创建更多嵌套子视图...


6
投票

简单回答:是的。

最好是创建一个名为views的目录,然后在你的urls.py中执行:

import views
...
url(r'^classroom$', views.school.klass, name="classroom"),

2
投票

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

成功了!!


1
投票
init

.py)。但是,我不会像某些答案所建议的那样导入 init.py 中的所有子视图。看起来效果很好。


1
投票


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 还很陌生,所以我仍在研究它对速度/安全性/易用性有什么影响。


1
投票
password_generator.py

的文件,然后在

views.py
中添加:
from password_generator import *

然后你可以从

views.py

调用该模块的函数。

    


0
投票
2024 年评论:

我也想在 Django 5 中执行此操作,并尝试将views.py 拆分为不同的文件,但失败了。在阅读了如何处理更多复杂性后,例如2022年的答案
,建议不要拆分views.py,而是根据应用程序的功能而不是模型将应用程序拆分为不同的应用程序。每个应用程序都有自己的views.py

© www.soinside.com 2019 - 2024. All rights reserved.