2012-04-25 6 views
5

Ich habe eine Frage zum Setzen von Django-Apps in "Apps" -Unterverzeichnis. Ich habe die App "faktura" in einem Projektstammverzeichnis. Mir gefiel nicht, dass es dort liegt und ich alle meine Apps im Unterverzeichnis "apps" ablegen möchte.Moving django apps in Unterordner und url.py Fehler

So fand ich heraus, dass ich Python-Pfad zu "apps" -Unterverzeichnis erweitern konnte, so nach dem Suchen im Internet, fügte ich diese Zeichenfolge zu settings.py: sys.path.insert (0, os.path.join (PROJECT_PATH, "apps")). Dann habe ich die App zu INSTALLED_APPS wie "faktura" hinzugefügt. Alles funktionierte reibungslos, bis ich urls.py im root url (r '^ faktura /', include ('faktura.urls')) hinzugefügt habe. Seit dem wirft Django die Fehlermeldung "Kein Modul mit dem Namen faktura" voll taceback ist hier: http://dpaste.com/737380/

Was kann hier falsch sein, warum nur urls.py kann die App nicht finden? Und kann es diese App nicht finden, wenn ich es dem PATH hinzugefügt habe? Ich habe einen Morgen damit verbracht, herauszufinden, was los ist und jetzt brauche ich deine Hilfe.

Antwort

1

Um Ihre Django-Anwendungen in einem Unterordner (zB apps /) zu halten, zuerst folgendes zu Ihrem settings.py hinzufügen:

import os

PROJECT_ROOT = os.path.dirname(__file__)

Dann in manage.py:

!

rechts unter #/usr/bin/env python add:

import sys

from os.path import abspath, dirname, join

from site import addsitedir

Kurz vor, wenn __name__ == "__main__": add:

sys.path.insert(0, join(settings.PROJECT_ROOT, "apps"))

+1

Yep dieses funktioniert ... aber wenn Sie - wie ich - uwsgi als App-Server verwenden, dann sollten Sie auch die Einfügung in die Datei wsgi.py anwenden. – Paul

+1

Benötigen Sie wirklich die ungenutzten Importe (addsitedir, dirname, abspath)? Oder sind sie von einer früheren Version dieser Antwort übrig geblieben? –

+1

Das Ändern von sys.path ist eine schlechte Idee. https://youtu.be/bAcfPzxB3dk?t=233 –

9

Ich weiß nicht, warum die vorherige Antwort bekam -1 abgesehen von vielleicht ein paar redundante Zeilen, die korrigiert werden können. Wie auch immer, ich habe eine etwas andere Methode gefunden, die nichts mit dem Python-Pfad zu tun hat.

Dies ist meine letzte Verzeichnisstruktur, die ich in einem Moment erklären:

mysite 
├── mysite 
│ ├── __init__.py 
│ ├── settings.py 
│ ├── urls.py 
│ └── wsgi.py 
├── apps 
│ ├── __init__.py 
│ └── myfirstapp 
│  ├── __init__.py 
│  ├── admin.py 
│  ├── models.py 
│  ├── tests.py 
│  └── views.py 
└── manage.py 

Egal, ob Sie gerade Ihr Projekt erstellt haben oder wenn Sie Ihre Anwendungen verschieben möchten, erstellen Sie das apps Unterverzeichnis, das enthalten sollte deine Apps Der Trick besteht darin, ein __init__.py zu diesem Verzeichnis hinzuzufügen.

mkdir apps 
touch apps/__init__.py 

Jetzt können Sie Ihre vorhandenen Anwendungen in das apps Unterverzeichnis verschieben. Wenn Sie einen neuen möchten stattdessen hier schaffen, sind die Befehle:

python manage.py mysecondapp 
mv mysecondapp apps/ 

Achtung: Nicht zu nennen python manage.py ./apps/mysecondapp versucht werden. Aus irgendeinem Grund löscht dies alle anderen Anwendungen in diesem Verzeichnis. Ich habe gerade einen Arbeitstag verloren.

Als nächstes müssen Sie ein paar Importe beheben.urls.py

INSTALLED_APPS = (
    ... 
    'apps.myfirstapp', 
    'apps.mysecondapp' 
) 

Schließlich reparieren Ihr Projekt apps Präfix: Ihr settings.py sollte mit apps vorangestellt werden

urlpatterns = patterns('', 
    url(r'^myfirstapp', include('apps.myfirstapp.urls')), 
    ... 
) 

Je nachdem, wie Sie schrieb sie, könnte man auch ein paar Importe in Ihrem beheben müssen App Entweder einfach from models import MyFirstModel verwenden oder auch mit from apps.myfirstapp.models import MyFirstModel voranstellen.

Kurz gesagt, wenn Sie Ihr apps Verzeichnis ein Python-Paket machen (indem Sie __init__.py hinzufügen), können Sie es als Teil des Importpfades verwenden. Dies sollte unabhängig von der Bereitstellungsmethode ohne zusätzliche Konfiguration funktionieren.

+0

Ich stieß auf ein Problem, das in dieser Antwort nicht angesprochen wurde, in dem die urls.py in apps/myfirstapp das erste Argument der Muster (...) setze auf 'apps.myfirstapp', wie zuvor ich es bewegt habe, es gelesen nur 'myfirstapp'. Djangos Debug-Ausgabe war dafür viel weniger als hilfreich. – Ethereal

+1

von apps.myfirstapp.models Import MyFirstModel funktioniert nicht in der Secondapps-Modelldatei .. weiß nicht warum .. – tyan

0

@Radu Gheorghius Antwort; Es ist nicht notwendig, settings.py zu bearbeiten, und die Zeile für den Einfügepfad kann auf 1 Codezeile reduziert werden.

sys.path.insert(0, os.path.join(os.path.dirname(__file__), "apps")) 

sourced ich diese Antwort von http://obroll.com/nested-application-inside-apps-sub-folder-in-django-1-3/

+0

Bitte erstellen Sie keine Antwort auf eine Antwort. Wenn Sie Radus Antwort etwas hinzufügen möchten, verwenden Sie die Kommentarfunktion. – Silicomancer

1

Verwenden BASE_DIR Variable aus der settings.py. Es sollte bereits definiert:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 

Besser nicht das __file__ Attribut in manage.py verwenden und wsgi.py, wie sie in verschiedenen Verzeichnissen befinden.

So fügen Sie einfach folgendes manage.py und wsgi.py (und die celery.py, wenn Sie verwenden, Sellerie):

from django.conf import settings 
    sys.path.append(os.path.join(settings.BASE_DIR, "apps")) 

Sie werden mit der folgenden Projektstruktur am Ende:

project 
├── project 
│ ├── __init__.py 
│ ├── celery.py 
│ ├── settings.py 
│ ├── urls.py 
│ └── wsgi.py 
├── apps 
│ ├── app1 
│ └── app2 
└── manage.py