Split views.py menjadi beberapa file

153

Saya views.pymenjadi terlalu besar dan sulit untuk menemukan pandangan yang benar.

Bagaimana cara membaginya dalam beberapa file dan kemudian mengimpornya? Apakah ini melibatkan kehilangan kecepatan?

Bisakah saya melakukan hal yang sama models.py?

Barin
sumber
4
Saya membagi file views.py besar (7k baris) saya untuk memisahkan file dan peningkatan kecepatan sangat signifikan.
user1261774

Jawaban:

190

Dalam Django semuanya adalah modul Python (* .py). Anda dapat membuat folder tampilan dengan bagian __init__.pydalam dan Anda masih dapat mengimpor tampilan Anda, karena ini juga mengimplementasikan modul Python. Tetapi sebuah contoh akan lebih baik.

Dokumen asli Anda views.pymungkin terlihat seperti ini:

def view1(arg):
    pass

def view2(arg):
   pass

Dengan struktur folder / file berikut ini akan berfungsi sama:

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 cepat penjelasan akan: ketika Anda menulis from views import view1Python akan mencari view1 di

  1. views.py, itulah yang terjadi pada kasus pertama (asli)

  2. views/__init__.py, Itulah yang terjadi pada kasus kedua. Di sini, __init__.pydapat menyediakan metode view1 karena mengimpornya.

Dengan solusi semacam ini, Anda mungkin tidak perlu mengubah importatau urlpatternargumenurls.py

Jika Anda memiliki banyak metode di setiap file tampilan baru, Anda mungkin merasa berguna untuk membuat impor views/__init__.pydigunakan *, seperti ini:

from viewsa import *
from viewsb import *

Saya sebenarnya tidak tahu tentang masalah kecepatan (tapi saya ragu ada).

Untuk Model mungkin agak sulit.

Vincent Demeester
sumber
2
Bisakah Anda menambahkan pola url yang cocok dengan view1 atau view2 dalam contoh Anda? Karena saya mengalami masalah dengan itu ....
Pascal Klein
2
Saya mencoba melakukan ini, tetapi ketika saya pergi untuk mengimpor model saya (dari app.models impor MyModel atau dari model impor MyModel) Python mengeluh bahwa model itu tidak ada.
Chris Miller
Tidak apa-apa jika kita menghapus views.py di direktori root?
Roel
6
Solusi ini tidak berfungsi untuk saya (kesalahan yang sama dengan untuk @ChrisMiller. Solusi saya: di __init__.py:. from myapp.views.viewsa import *Perhatikan bahwa Anda tidak dapat memiliki views.py lagi (atau setidaknya tidak akan dibaca @ShiftNTab: Kesalahan karena tidak menemukan pandangan Anda di views.py). Semoga bermanfaat!
ThePhi
Bagaimana dengan konvensi penamaan: apakah nama file harus tunggal atau jamak? Contoh: views.car.pyvsviews.cars.py
guival
21

Saya harus melakukan ini sebelumnya (demi kejelasan)

Cara saya melakukan ini adalah membuat viewsdirektori, lalu, dalam hal itu, buat file bernama__init__.py

Sekarang, ketika Anda memanggil Anda urls.py, Anda hanya perlu menambahkan bagian lain

Misalnya, sebelumnya, Anda mungkin telah menelepon: -

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

Anda sekarang dapat memanggil sesuatu di sepanjang baris

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

Ini, tentu saja, dengan asumsi bahwa Anda telah views/year.pymengandung fungsi indexdan user;)

Mez
sumber
10

Pada dasarnya, Anda dapat meletakkan kode Anda, di mana pun Anda inginkan. Pastikan saja, Anda mengubah laporan impor yang sesuai, misalnya untuk tampilan dalam urls.py.

Tidak mengetahui kode Anda yang sebenarnya sulit untuk menyarankan sesuatu yang bermakna. Mungkin Anda dapat menggunakan beberapa jenis awalan nama file, misalnya views_helper.py, views_fancy.py, views_that_are_not_so_often_used.pyatau lebih ...

Pilihan lain adalah membuat viewsdirektori dengan __init__.py, tempat Anda mengimpor semua subview . Jika Anda membutuhkan banyak file, Anda dapat membuat lebih banyak subview bersarang saat tampilan Anda bertambah ...

miku
sumber
8

Hanya untuk berbagi, saya punya sedikit masalah dengan jawaban Vincent Demeester. Semuanya baik-baik saja kecuali dalam file init .py, saya harus menulis dengan cara ini:

__init__.py :

from .viewsa import *
from .viewsb import *

Dengan cara ini saya masih tidak perlu mengubah importmetode saya di urls.py. Saya menggunakan Python 3.6.1 dan Django 1.11.4 .

kecanduan
sumber
5

Jawaban sederhana: Ya.

Yang terbaik adalah membuat direktori bernama views dan kemudian di urls.py Anda lakukan:

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

Saya membagi hampir semua tampilan di aplikasi saya menjadi folder tampilan ( tentu saja dengan init .py). Saya tidak, bagaimanapun, mengimpor semua subview di init .py seperti beberapa jawaban yang disarankan. Tampaknya bekerja dengan baik.

DrBloodmoney
sumber
1

Karena Django hanya mengharapkan tampilan menjadi objek yang bisa dipanggil, Anda dapat menempatkannya di mana pun Anda suka di PYTHONPATH Anda. Jadi Anda bisa misalnya hanya membuat paket baru myapp.views dan meletakkan view ke beberapa modul di sana. Anda secara alami harus memperbarui urls.py Anda dan modul lain yang mereferensikan tampilan tampilan ini.

Horst Gutmann
sumber
1
Ini sebenarnya salah - ini bisa dilakukan dengan model. Lihat: code.djangoproject.com/ticket/4470
Jonathan Berger
1
Ah, senang tahu, terima kasih :-) Saya selalu berpikir ada sedikit lebih banyak keajaiban yang terlibat dengan model dan bagaimana mereka hidup dalam paket aplikasi. Menghapus garis tentang model dalam respons saya.
Horst Gutmann
Senang saya bisa membantu, saya menyadari kemudian bahwa tautan ini benar-benar menjelaskan bagaimana ini dilakukan dengan model yang jauh lebih baik: blog.amber.org/2009/01/19/…
Jonathan Berger
1

Saya telah bermain dengan meletakkan ini di 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))

Saya masih baru di python, jadi saya masih melihat apa efeknya pada kecepatan / keamanan / kemudahan penggunaan.

EToS
sumber
1

Misalkan jika Anda memiliki file bernama: password_generator.pythen inside views.pyadd:from password_generator import *

Kemudian Anda dapat memanggil fungsi modul itu dari views.py.

Abhay
sumber
1

Jawaban Vincent Demeester luar biasa! tetapi bagi saya jawaban kecanduan bekerja seperti pesona. Saya menghadapi kesulitan dalam memigrasi basis data. Kesalahan menunjukkan garis di mana model pertama diimpor dan mengatakan tidak bisa mengenali modul aplikasi saya. Mencari banyak tetapi tidak dapat menemukan solusi tetapi kemudian saya mengimpor model seperti ini:

from ..models import ModelName

Berhasil !!

Bashar
sumber