Разделить views.py в нескольких файлах - PullRequest
140 голосов
/ 17 декабря 2009

Мой views.py стал слишком большим, и трудно найти правильный вид.

Как мне разбить его на несколько файлов и затем импортировать? Это связано с потерей скорости?

Могу ли я сделать то же самое с models.py?

Ответы [ 9 ]

171 голосов
/ 17 декабря 2009

В 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

Объяснение quick будет следующим: при написании from views import view1 Python будет искать view1 в

  1. views.py, что происходит в первом (оригинальном) случае

  2. views/__init__.py, что и происходит во втором случае. Здесь __init__.py может предоставить метод view1, потому что он его импортирует.

При таком решении вам может не понадобиться изменять import или urlpattern s аргументы в urls.py

Если у вас есть много методов в каждом новом файле представления, может оказаться полезным, чтобы при импорте в views/__init__.py использовался *, например:

from viewsa import *
from viewsb import *

Я действительно не знаю о проблемах со скоростью (но я сомневаюсь, что они есть).

Для моделей это может быть немного сложно.

20 голосов
/ 17 декабря 2009

Я должен был сделать это раньше (для ясности)

Я сделал так, чтобы создать каталог 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;)

9 голосов
/ 17 декабря 2009

В принципе, вы можете поместить свой код, куда пожелаете. Просто убедитесь, что вы изменили операторы импорта соответственно, например, для просмотров в urls.py.

Не зная вашего реального кода, трудно предложить что-то осмысленное. Может быть, вы можете использовать какой-то префикс имени файла, например views_helper.py, views_fancy.py, views_that_are_not_so_often_used.py или около того ...

Другой вариант - создать каталог views с __init__.py, куда вы импортируете все подпредставления . Если вам нужно большое количество файлов, вы можете создавать больше вложенных подпредставлений по мере роста ваших просмотров ...

6 голосов
/ 08 сентября 2017

Просто для того, чтобы поделиться, у меня возникли некоторые проблемы с ответом Винсента Деместера. Все хорошо, кроме init .py файла, я должен написать так:

__ __ INIT ого :.

from .viewsa import *
from .viewsb import *

Таким образом, мне все еще не нужно менять мой import метод в urls.py. Я на Python 3.6.1 и Django 1.11.4 .

5 голосов
/ 17 декабря 2009

Простой ответ: Да.

Лучше всего создать каталог с именем views, а затем в вашем urls.py сделать:

import views
...
url(r'^classroom$', views.school.klass, name="classroom"),
1 голос
/ 19 августа 2015

Предположим, если у вас есть файл с именем: password_generator.py, то внутри views.py добавьте: from password_generator import *

Затем вы можете вызвать функцию этого модуля из views.py.

1 голос
/ 27 января 2011

Я играл с этим в моем 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 голос
/ 17 декабря 2009

Я разделил почти все представления в моих приложениях в папку представлений (конечно, с init .py). Однако я не импортирую все подпредставления в init .py, как предлагалось в некоторых ответах. Кажется, работает просто отлично.

1 голос
/ 17 декабря 2009

Поскольку Django ожидает, что представление является вызываемым объектом, вы можете поместить его в любое место в своей PYTHONPATH. Таким образом, вы можете, например, просто сделать новый пакет myapp.views и поместить представления в несколько модулей. Вам, естественно, придется обновить свой urls.py и другие модули, которые ссылаются на эти вызываемые представления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...