Teilen Sie views.py in mehrere Dateien auf

153

Mein views.pyist zu groß geworden und es ist schwer, die richtige Ansicht zu finden.

Wie teile ich es in mehrere Dateien auf und importiere es dann? Handelt es sich um einen Geschwindigkeitsverlust?

Kann ich das auch mit machen models.py?

Barin
quelle
4
Ich habe meine große Datei views.py (7.000 Zeilen) aufgeteilt, um Dateien zu trennen, und die Geschwindigkeitssteigerung war erheblich.
user1261774

Antworten:

190

In Django ist alles ein Python-Modul (* .py). Sie können einen Ansichtsordner mit einer __init__.pyInnenseite erstellen und Ihre Ansichten weiterhin importieren, da hierdurch auch ein Python-Modul implementiert wird. Aber ein Beispiel wäre besser.

Ihr Original views.pykönnte folgendermaßen aussehen:

def view1(arg):
    pass

def view2(arg):
   pass

Mit der folgenden Ordner- / Dateistruktur funktioniert es genauso:

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

Die schnelle Erklärung wäre: Wenn Sie schreiben from views import view1, sucht Python nach view1 in

  1. views.py, was im ersten (ursprünglichen) Fall passiert

  2. views/__init__.py, was im zweiten Fall passiert. Hier kann __init__.pydie view1-Methode bereitgestellt werden, da sie importiert wird.

Mit dieser Art von Lösung müssen Sie möglicherweise keine Argumente ändern importoder ändernurlpatternurls.py

Wenn Sie viele Methoden in jedem neuen View - Datei haben, ist es möglicherweise sinnvoll , die Importe in machen views/__init__.pyGebrauch *, wie folgt aus :

from viewsa import *
from viewsb import *

Ich weiß eigentlich nichts über Geschwindigkeitsprobleme (aber ich bezweifle, dass es welche gibt).

Für Models könnte es etwas schwierig sein.

Vincent Demeester
quelle
2
Könnten Sie bitte ein URL-Muster hinzufügen, das in Ihrem Beispiel mit view1 oder view2 übereinstimmt? Weil ich Probleme damit habe ...
Pascal Klein
2
Ich habe es versucht, aber wenn ich meine Modelle importiere (aus app.models importiere MyModel oder aus Models importiere MyModel), beschwert sich Python, dass das Modell nicht existiert.
Chris Miller
Ist es in Ordnung, wenn wir die views.py im Stammverzeichnis löschen?
Roel
6
Diese Lösung funktioniert bei mir nicht (der gleiche Fehler wie bei @ChrisMiller. Meine Lösung: in __init__.py: from myapp.views.viewsa import *. Beachten Sie, dass Sie keine views.py mehr haben können (oder zumindest nicht gelesen wird @ShiftNTab: Fehler für nicht Finden Sie Ihre Ansichten in views.py). Hoffe, es hilft!
ThePhi
Was ist mit der Namenskonvention: Sollte der Dateiname Singular oder Plural sein? ZB: views.car.pyvsviews.cars.py
Guival
21

Ich musste das schon einmal machen (aus Gründen der Klarheit)

Die Art und Weise, wie ich dies tat, bestand darin, ein viewsVerzeichnis zu erstellen und dann eine Datei mit dem Namen zu erstellen__init__.py

Wenn Sie jetzt Ihren Anruf tätigen urls.py, müssen Sie lediglich einen weiteren Teil hinzufügen

Zum Beispiel haben Sie zuvor angerufen: -

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

Sie können jetzt etwas in der Art von aufrufen

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

Dies setzt natürlich voraus, dass Sie views/year.pydie Funktionen enthalten haben indexund user;)

Mez
quelle
10

Grundsätzlich können Sie Ihren Code beliebig eingeben. Stellen Sie einfach sicher, dass Sie die Importanweisungen entsprechend ändern, z. B. für die Ansichten in der urls.py.

Wenn Sie Ihren tatsächlichen Code nicht kennen, ist es schwierig, etwas Sinnvolles vorzuschlagen. Vielleicht können Sie irgendeine Art von Dateinamenpräfix verwenden, zB views_helper.py, views_fancy.py, views_that_are_not_so_often_used.pyoder so ...

Eine andere Möglichkeit wäre, ein viewsVerzeichnis mit einem zu erstellen __init__.py, in das Sie alle Unteransichten importieren . Wenn Sie eine große Anzahl von Dateien benötigen, können Sie mehr verschachtelte Unteransichten erstellen, wenn Ihre Ansichten wachsen ...

miku
quelle
8

Nur zum Teilen hatte ich ein paar Probleme mit Vincent Demeesters Antwort. Alles ist in Ordnung, außer in der init .py-Datei muss ich folgendermaßen schreiben:

__init__.py :

from .viewsa import *
from .viewsb import *

Auf diese Weise muss ich meine importMethode in urls.py immer noch nicht ändern. Ich bin auf Python 3.6.1 und Django 1.11.4 .

süchtig
quelle
5

Einfache Antwort: Ja.

Am besten erstellen Sie ein Verzeichnis mit dem Namen views und führen dann in Ihrer urls.py Folgendes aus:

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

Ich habe fast alle Ansichten in meinen Apps in einen Ansichtsordner aufgeteilt ( natürlich mit einer init .py). Ich importiere jedoch nicht alle Unteransichten in die init .py, wie einige der Antworten vorgeschlagen haben. Es scheint gut zu funktionieren.

DrBloodmoney
quelle
1

Da Django nur erwartet, dass eine Ansicht ein aufrufbares Objekt ist, können Sie sie in Ihren PYTHONPATH einfügen, wo immer Sie möchten. So können Sie beispielsweise einfach ein neues Paket myapp.views erstellen und dort Ansichten in mehrere Module einfügen. Sie müssen natürlich Ihre urls.py und andere Module aktualisieren, die auf diese View-Callables verweisen.

Horst Gutmann
quelle
1
Dies ist eigentlich falsch - es kann mit Modellen gemacht werden. Siehe: code.djangoproject.com/ticket/4470
Jonathan Berger
1
Ah, gut zu wissen, danke :-) Ich dachte immer, dass Modelle etwas mehr Magie beinhalten und wie sie im App-Paket leben. Die Zeile über Modelle in meiner Antwort wurde entfernt.
Horst Gutmann
Ich bin froh, dass ich helfen konnte, und später wurde mir klar, dass dieser Link tatsächlich erklärt, wie es mit Modellen viel besser gemacht wird: blog.amber.org/2009/01/19/…
Jonathan Berger
1

Ich habe damit gespielt, dies in meine Init .py zu schreiben:

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

Ich bin noch neu in Python, also schaue ich mir immer noch an, welche Auswirkungen es auf Geschwindigkeit / Sicherheit / Benutzerfreundlichkeit hat.

EToS
quelle
1

Angenommen, Sie haben eine Datei mit dem Namen: password_generator.pyund views.pyfügen Sie hinzu:from password_generator import *

Dann können Sie die Funktion dieses Moduls von aufrufen views.py.

Abhay
quelle
1

Die Antwort von Vincent Demeester ist hervorragend! aber für mich wirkte die Antwort des Süchtigen wie ein Zauber. Ich hatte Schwierigkeiten bei der Migration der Datenbank. Der Fehler zeigt die Zeile an, in die das erste Modell importiert wird, und besagt, dass mein App-Modul nicht erkannt werden konnte. Viel gesucht, aber keine Lösung gefunden, aber später habe ich das Modell folgendermaßen importiert:

from ..models import ModelName

Es funktionierte!!

Bashar
quelle