将views.py拆分为多个文件

问题:将views.py拆分为多个文件

我的views.py体积太大了,很难找到正确的视图。

如何将其拆分为多个文件,然后导入?是否涉及速度损失?

我可以这样models.py吗?

My views.py has become too big and it’s hard to find the right view.

How do I split it in several files and then import it? Does it involve any speed loss?

Can I do the same with models.py?


回答 0

在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会寻找在厂景

  1. views.py,这就是第一种(原始)情况

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

使用这种解决方案,您可能无需更改import或更改urlpattern参数urls.py

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

from viewsa import *
from viewsb import *

我实际上不了解速度问题(但我怀疑是否有任何问题)。

对于模型而言,可能有点困难。

In Django everything is a Python module (*.py). You can create a view folder with an __init__.py inside and you still will be able to import your views, because this also implements a Python module. But an example would be better.

Your original views.py might look like this :

def view1(arg):
    pass

def view2(arg):
   pass

With the following folder/file structure it will work the same :

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

The quick explanation would be: when you write from views import view1 Python will look for view1 in

  1. views.py, which is what happens in the first (original) case

  2. views/__init__.py, which is what happens in the second case. Here, __init__.py is able to provide the view1 method because it imports it.

With this kind of solution, you might have no need to change import or urlpatterns arguments in urls.py

If you have many methods in each new view file, you might find it useful to make the imports in views/__init__.py use *, like this:

from viewsa import *
from viewsb import *

I actually don’t know about speed issues (but I doubt there are any).

For Models it might be a bit difficult.


回答 1

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

我这样做的方法是创建一个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;)

I’ve had to do this before (for clarities sake)

The way I did this was to create a views directory, then, in that, create a file called __init__.py

Now, when you’re calling in your urls.py, you simply need to add another part

For example, previously, you may have called:-

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

You can now call something along the lines of

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

This is, of course, assuming that you had views/year.py containing the functions index and user ;)


回答 2

基本上,您可以将代码放在任意位置。只需确保您相应地更改了导入语句,例如针对中的视图即可urls.py

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

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

Basically, you can put your code, whereever you wish. Just make sure, you change the import statements accordingly, e.g. for the views in the urls.py.

Not knowing your actual code its hard to suggest something meaningful. Maybe you can use some kind of filename prefix, e.g. views_helper.py, views_fancy.py, views_that_are_not_so_often_used.py or so …

Another option would be to create a views directory with an __init__.py, where you import all subviews. If you have a need for a large number of files, you can create more nested subviews as your views grow …


回答 3

只是为了分享,文森特·德梅斯特(Vincent Demeester)的回答有点问题。除了init .py文件外,一切都很好,我必须这样写:

__init__.py

from .viewsa import *
from .viewsb import *

这样,我仍然不需要import在urls.py中更改我的方法。我正在使用Python 3.6.1Django 1.11.4

Just for sharing, I had a bit of issues with Vincent Demeester’s answer. Everything is fine except in init.py file, I have to write in this way:

__init__.py:

from .viewsa import *
from .viewsb import *

This way I still don’t need to change my import method in urls.py. I am on Python 3.6.1 and Django 1.11.4.


回答 4

简单的答案:是的。

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

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

Simple answer: Yes.

Best is to make a directory called views and then in your urls.py do:

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

回答 5

我将应用程序中的几乎所有视图都拆分为一个views文件夹(当然还有一个init .py)。但是,我不像某些答案所建议的那样将所有子视图导入init .py中。似乎工作正常。

I split almost all views in my apps into a views folder (with an init.py of course). I do not, however, import all of the subviews in the init.py like some of the answers have suggested. It seems to work just fine.


回答 6

由于Django只希望视图是可调用的对象,因此您可以将其放置在PYTHONPATH中的任何位置。因此,您可以例如仅创建一个新程序包myapp.views并将视图放入那里的多个模块中。自然,您将不得不更新urls.py和其他引用这些视图可调用对象的模块。

Since Django just expects a view to be a callable object, you can put then wherever you like in your PYTHONPATH. So you could for instance just make a new package myapp.views and put views into multiple modules there. You will naturally have to update your urls.py and other modules that reference these view callables.


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

I’ve been playing with putting this in my 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))

I’m still new to python, so I’m still looking at what effect it has on speed/security/ease of use.


回答 8

假设您有一个名为:的文件,password_generator.py然后在其中views.py添加:from password_generator import *

然后,您可以从调用该模块的功能views.py

Suppose if you have a file named: password_generator.py then inside views.py add: from password_generator import *

Then you can call that module’s function from views.py.


回答 9

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

from ..models import ModelName

有效!!

Vincent Demeester‘s answer is superb! but for me addicted‘s answer worked like a charm. I faced difficulties in migrating database. The error indicates the line where the first model is imported and says could not recognize my app module. Searched a lot but could not find a solution but later on I imported the model like this:

from ..models import ModelName

It worked!!