Розділіть views.py на кілька файлів


153

Моє views.pyстало занадто великим і важко знайти правильний вигляд.

Як розділити його на кілька файлів, а потім імпортувати? Чи пов'язано це з втратою швидкості?

Чи можу я те ж саме зробити models.py?


4
Я розділив свій великий (7k рядків) файл views.py на окремі файли, і збільшення швидкості було значним.
користувач1261774

Відповіді:


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, що відбувається у другому випадку. Тут __init__.pyможна надати метод view1, оскільки він імпортує його.

З таким рішенням, можливо, вам не доведеться змінювати аргументи importабо urlpatternsurls.py

Якщо у кожному новому файлі перегляду є багато методів, вам може бути корисно зробити імпорт у views/__init__.pyвикористанні *, наприклад, таким:

from viewsa import *
from viewsb import *

Я насправді не знаю про проблеми зі швидкістю (але я сумніваюся, що вони є).

Для моделей це може бути дещо складно.


2
Чи можете ви додати у своєму прикладі шаблон URL-адреси, який відповідає view1 або view2? Тому що у мене проблеми з цим ....
Паскаль Кляйн

2
Я намагався це робити, але коли я переходжу до імпорту моїх моделей (з app.models import MyModel або з моделей імпорту MyModel), Python скаржиться, що моделі не існує.
Кріс Міллер

Це нормально, якщо ми видалимо views.py в кореневій директорії?
Roel

6
Це рішення не працює для мене (така ж помилка, як і для @ChrisMiller. Моє рішення: в __init__.py:. from myapp.views.viewsa import *Зауважте, що ви більше не можете мати view.py (або принаймні не буде прочитано @ShiftNTab: Помилка не знайти свої погляди в views.py) Сподіваюся, що це допоможе!
ThePhi

Що з умовою іменування: чи ім’я файлу має бути одниною чи множиною? Напр .: 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функції indexі user;)


10

В основному, ви можете покласти свій код, де завгодно. Просто переконайтеся, що ви відповідним чином змінили заяви про імпорт, наприклад, для переглядів у urls.py.

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

Іншим варіантом було б створити viewsкаталог з __init__.py, куди ви імпортуєте всі підгляди . Якщо у вас є потреба у великій кількості файлів, ви можете створювати більше вкладених підпідслідів у міру зростання ваших переглядів ...


8

Тільки для спільного використання у мене було небагато питань з відповіддю Вінсента Деместера. Все добре, крім файлу init .py, я повинен писати так:

__init__.py :

from .viewsa import *
from .viewsb import *

Таким чином мені все одно не потрібно міняти свій importметод в urls.py. Я на Python 3.6.1 та Django 1.11.4 .


5

Проста відповідь: так.

Найкраще створити каталог з назвою перегляди, а потім у вашому urls.py зробити:

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

1

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


1

Оскільки Джанго просто очікує, що вид буде об'єктом для дзвінка, ви можете розмістити його куди завгодно у своєму ПІТОНПАТІ. Таким чином, ви можете, наприклад, просто створити новий пакет myapp.views і помістити там перегляди в кілька модулів. Вам, природно, доведеться оновити urls.py та інші модулі, на які посилаються ці переглядачі.


1
Це насправді неправильно - це можна зробити за допомогою моделей. Дивіться: code.djangoproject.com/ticket/4470
Джонатан Бергер

1
Ах, добре знати, дякую :-) Я завжди думав, що в моделях і в тому, як вони живуть у пакеті додатків, є трохи більше магії. У моїй відповіді було видалено рядок про моделі.
Хорст Гутманн

Радий, що можу допомогти. Згодом зрозумів, що це посилання насправді пояснює, як це робиться з моделями набагато краще: 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.pyadd:from password_generator import *

Тоді ви можете викликати функцію цього модуля views.py.


1

Відповідь Вінсента Деместера - чудова! але відповідь для мене залежно працювала як принадність. Я зіткнувся з труднощами при переміщенні бази даних. Помилка вказує рядок, куди імпортується перша модель, і каже, що не вдалося розпізнати мій модуль програми. Шукали багато, але не змогли знайти рішення, але пізніше я імпортувала таку модель:

from ..models import ModelName

Це спрацювало!!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.