Views.py dosyasını birkaç dosyaya böl


153

Benim views.pyçok büyük oldu ve doğru görüşü bulmak zor.

Nasıl birkaç dosyaya bölerim ve sonra alabilirim? Herhangi bir hız kaybı içeriyor mu?

Ben de aynısını yapabilir miyim models.py?


4
Büyük (7k satır) views.py dosyamı dosyaları ayrı olarak ayırdım ve hızdaki artış önemliydi.
user1261774

Yanıtlar:


190

Django'da her şey bir Python modülüdür (* .py). İçinde bir görünüm klasörü oluşturabilirsiniz __init__.pyve yine de görünümlerinizi içe aktarabilirsiniz, çünkü bu aynı zamanda bir Python modülü de uygular. Ama bir örnek daha iyi olurdu.

Orijinal views.pybelgeniz şöyle görünebilir:

def view1(arg):
    pass

def view2(arg):
   pass

Aşağıdaki klasör / dosya yapısıyla aynı şekilde çalışır:

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

Hızlı açıklama olacaktır: Eğer yazarken from views import view1Python içinde view1 arayacaktır

  1. views.py, ilk (orijinal) durumda olan şey budur

  2. views/__init__.py, ikinci durumda olan budur. Burada, __init__.pyview1 yöntemini içe aktardığı için sağlayabilir.

Bu tür bir çözümle, içindeki argümanları değiştirmeye importveyaurlpatternurls.py

Her yeni görünüm dosyasında çok sayıda yönteminiz varsa, içe aktarma işlemlerini views/__init__.pykullanımda yapmanın yararlı olduğunu görebilirsiniz *, örneğin:

from viewsa import *
from viewsb import *

Aslında hız sorunlarını bilmiyorum (ama şüpheliyim).

Modeller için biraz zor olabilir.


2
Lütfen örneğinizde view1 veya view2 ile eşleşen bir url kalıbı ekler misiniz? Çünkü bununla ilgili sorunlar yaşıyorum ....
Pascal Klein

2
Bunu yapmayı denedim, ancak modellerimi almaya gittiğimde (app.models'den MyModel'i içe aktarın veya modellerin MyModel'i içe aktarın) Python, modelin mevcut olmadığından şikayet ediyor.
Chris Miller

Kök dizindeki views.py dosyasını silersek sorun olmaz mı?
Roel

6
Bu çözüm @ChrisMiller için daha benim için işi (aynı hatayı yapmaz Benim çözüm:. İn __init__.py: from myapp.views.viewsa import *. Not artık bir views.py olamaz (veya en azından @ShiftNTab okumak olmayacak: Hata değil . views.py de sizin görüşlerinizi) bulma Umut yardımcı olur!
ThePhi

Adlandırma kuralı hakkında: dosya adı tekil mi yoksa çoğul mu olmalı? Ör: views.car.pyvsviews.cars.py
guival

21

Bunu daha önce yapmak zorunda kaldım (netlik uğruna)

Bunu yaptığım yol, bir viewsdizin oluşturmaktı , daha sonra,__init__.py

Şimdi, telefonunuzu ararken, urls.pybaşka bir parça eklemeniz yeterlidir.

Örneğin, daha önce şunu aramış olabilirsiniz: -

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

Artık bir şey diyebilirsiniz.

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

Bu, elbette, views/year.pyişlevleri içerdiğini varsayarak indexve user;)


10

Temel olarak, kodunuzu istediğiniz yere koyabilirsiniz. İçe aktarma ifadelerini buna göre değiştirdiğinizden emin olun, örn urls.py.

Gerçek kodunuzu bilmemek, anlamlı bir şey önermek zordur. Belki örn dosya adı öneki, bir çeşit kullanabilir views_helper.py, views_fancy.py, views_that_are_not_so_often_used.pyya da öylesine ...

Başka bir seçenek de , tüm alt görünümleri içe aktardığınızviews bir ile bir dizin oluşturmak olacaktır . Çok sayıda dosyaya ihtiyacınız varsa, görünümleriniz büyüdükçe daha iç içe alt görünümler oluşturabilirsiniz ...__init__.py


8

Sadece paylaşmak için Vincent Demeester'ın cevabı ile ilgili bazı sorunlar yaşadım. Her şey hariç cezası olan init'in .py dosyası, ben bu şekilde yazma vardır:

__init__.py :

from .viewsa import *
from .viewsb import *

Bu yolla importurls.py dosyasındaki yöntemimi değiştirmem gerekmiyor. Ben duyuyorum Python 3.6.1 ve Django 1.11.4 .


5

Basit cevap: Evet.

En iyisi, views adında bir dizin oluşturmak ve daha sonra urls.py dosyasında yapmaktır:

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

1

Uygulamalarımdaki neredeyse tüm görünümleri bir görüntüleme klasörüne böldüm (elbette init .py ile). Ancak, bazı yanıtların önerdiği gibi init .py dosyasındaki tüm alt görünümleri içe aktarmıyorum . İyi çalışıyor gibi görünüyor.


1

Django sadece bir görünümün çağrılabilir bir nesne olmasını beklediğinden, PYTHONPATH'ınızda istediğiniz yere koyabilirsiniz. Böylece myapp.views adlı yeni bir paket oluşturabilir ve orada birden fazla modüle görünüm koyabilirsiniz. Doğal olarak urls.py ve bu görünüm hesaplarına referans veren diğer modülleri güncellemeniz gerekir.


1
Bu aslında yanlış - modellerle yapılabilir. Bakınız: code.djangoproject.com/ticket/4470
Jonathan Berger

1
Ah, bilmek güzel, teşekkürler :-) Her zaman modellerle ve uygulama paketinde nasıl yaşadıklarıyla ilgili biraz daha sihir olduğunu düşündüm. Cevabımdaki modeller hakkındaki çizgi kaldırıldı.
Horst Gutmann

Yardımcı olabildiğime sevindim, daha sonra bu bağlantının modellerle nasıl yapıldığını çok daha iyi açıkladığını fark ettim: blog.amber.org/2009/01/19/…
Jonathan Berger

1

Bunu init .py'ye koyarak oynamaktayım :

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

Hala python için yeniyim, bu yüzden hala hız / güvenlik / kullanım kolaylığı üzerinde ne gibi etkilere bakıyorum.


1

Diyelim ki: adında bir dosyanız varsa password_generator.pyo zaman views.pyadd add:from password_generator import *

Sonra bu modülün işlevini çağırabilirsiniz views.py.


1

Vincent Demeester'in cevabı mükemmel! ama benim için bağımlıların cevabı bir cazibe gibi çalıştı. Veritabanını taşımada zorluklarla karşılaştım . Hata, ilk modelin içe aktarıldığı satırı gösterir ve uygulama modülümü tanıyamayacağını söylüyor. Çok aradım ama bir çözüm bulamadım ama daha sonra modeli böyle içe aktardım:

from ..models import ModelName

İşe yaradı!!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.