views.pyをいくつかのファイルに分割する


153

views.pyが大きくなりすぎて、正しい見方を見つけるのが難しい。

いくつかのファイルに分割してインポートする方法を教えてください。速度の低下はありますか?

同じことはできますmodels.pyか?


4
大きな(7k行)のviews.pyファイルをファイルに分割したところ、速度が大幅に向上しました。
user1261774

回答:


190

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 view1PythonがVIEW1で探します

  1. views.py、これは最初の(元の)ケースで何が起こるか

  2. views/__init__.py、これは2番目のケースで何が起こるかです。ここで__init__.pyは、view1メソッドをインポートするため、それを提供できます。

この種類のソリューションでは、引数を変更しimportたり、urlpattern引数を指定したりする必要がない場合があります。urls.py

新しいビューファイルごとに多くのメソッドがある場合、次のように、インポートをviews/__init__.py使用中にすると便利な場合があります*

from viewsa import *
from viewsb import *

私は実際には速度の問題については知りません(しかし、何かがあるとは思えません)。

モデルの場合、少し難しいかもしれません。


2
あなたの例でview1またはview2に一致するURLパターンを追加していただけませんか?私はそれに問題があるので....
Pascal Klein

2
これを試しましたが、モデルをインポートしようとすると(app.models import MyModelから、またはmodels import MyModelから)、Pythonはモデルが存在しないと不平を言っています。
Chris Miller

ルートディレクトリのviews.pyを削除してもよろしいですか?
Roel、2016

6
この解決策は私にとっては機能しません(@ChrisMillerと同じエラーです。私の解決策:で__init__.pyfrom myapp.views.viewsa import *。views.pyをもう使用できないことに注意してください(または、少なくとも@ShiftNTabを読み取れません):Not for not views.pyであなたの意見を見つけてください。それが役に立てば
幸い

命名規則についてはどうですか:ファイル名は単数または複数のどちらにする必要がありますか?例:views.car.pyvsviews.cars.py
guival

21

私は以前にこれをしなければなりませんでした(明確にするために)

私がこれをした方法は、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;)が含まれていることを前提としています。


10

基本的に、コードはどこにでも置くことができます。必ず確認してくださいurls.py。たとえば、のビューの場合は、それに応じてインポート文を変更してください。

実際のコードがわからないため、意味のあるものを提案するのは困難です。たぶん、あなたは例えば、ファイル名の先頭のいくつかの種類を使用することができviews_helper.pyviews_fancy.pyviews_that_are_not_so_often_used.pyまたはそう...

別のオプションは、すべてのサブビューをインポートviewsする__init__.pyでディレクトリを作成することです。多数のファイルが必要な場合は、ビューが大きくなるにつれてネストされたサブビューをさらに作成できます...


8

共有するためだけに、私はVincent Demeesterの回答に少し問題がありました。init .pyファイル以外はすべて問題ありません。このように記述します。

__init__.py

from .viewsa import *
from .viewsb import *

この方法でもimport、urls.pyのメソッドを変更する必要はありません。私はPython 3.6.1Django 1.11.4を使用しています。


5

簡単な答え:はい。

最善の方法は、viewsというディレクトリを作成し、次にurls.pyで次のようにします。

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

1

アプリのほとんどすべてのビューをビューフォルダーに分割します(もちろんinit .pyを使用)。ただし、一部の回答が示唆しているように、init .pyのすべてのサブビューをインポートしません。正常に動作するようです。


1

Djangoはビューが呼び出し可能なオブジェクトであることを期待しているだけなので、PYTHONPATHの好きな場所に置くことができます。たとえば、新しいパッケージmyapp.viewsを作成して、そこにある複数のモジュールにビューを配置することができます。当然、これらのビューの呼び出し可能オブジェクトを参照するurls.pyおよびその他のモジュールを更新する必要があります。


1
これは実際には正しくありません-モデルで実行できます。参照:code.djangoproject.com/ticket/4470
Jonathan Berger

1
ああ、知ってよろしくお願いします:-)私はいつも、モデルと、アプリパッケージ内でのモデルの扱い方にもう少し魔法が必要だと思っていました。私の応答でモデルに関する行を削除しました。
Horst Gutmann、2011

:私は助けることがうれしい、私は、このリンクは、実際にそれがはるかに優れたモデルで行うの方法を説明することを後で実現blog.amber.org/2009/01/19/...
ジョナサン・バーガー

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


1

Vincent Demeesterの答えはすばらしいです。しかし私にとっては、中毒の答えは魅力のように働きました。データベースの移行に苦労しました。このエラーは、最初のモデルがインポートされた行を示し、アプリモジュールを認識できなかったことを示しています。多くを検索しましたが、解決策は見つかりませんでしたが、後で次のようにモデルをインポートしました。

from ..models import ModelName

出来た!!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.