2012-04-25 10 views
5

Ho una domanda su come mettere le app di django nella sottodirectory "apps". Ho l'app chiamata "faktura" in un progetto_root. Non mi piaceva il fatto che giacesse lì e voglio memorizzare tutte le mie app nella sottodirectory "apps".Spostamento di app django in sottocartella e url.py errore

Quindi, ho scoperto che potrei estendere il percorso Python al sottodirectory "apps", quindi dopo aver guardato su Internet, ho aggiunto questa stringa a settings.py: sys.path.insert (0, os.path.join (PROJECT_PATH, "app")). Poi ho aggiunto l'app a INSTALLED_APPS come "faktura". Tutto ha funzionato fino a quando ho aggiunto url (r '^ faktura /', include ('faktura.urls')) a urls.py nella radice. Dal momento che, Django lancia il messaggio di errore “No module named faktura” taceback completo è qui: http://dpaste.com/737380/

Che cosa può essere sbagliato, perché solo urls.py non può trovare l'applicazione? E non riesce a trovare questa app se l'ho aggiunta al PERCORSO? Ho passato una mattinata cercando di capire cosa c'è che non va e ora ho bisogno del tuo aiuto.

risposta

1

Per mantenere le applicazioni Django in una sottocartella (come ad esempio apps /), prima aggiungere il seguente al vostro settings.py:

import os

PROJECT_ROOT = os.path.dirname(__file__)

Poi nel manage.py:

!

Proprio sotto #/usr/bin/env python aggiuntivo:

import sys

from os.path import abspath, dirname, join

from site import addsitedir

Poco prima if __name__ == "__main__": aggiungere:

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

+1

Yep questo funziona ... ma se usi - come faccio io - uwsgi come app server, dovresti anche applicare l'insert nel file wsgi.py. – Paul

+1

Avete davvero bisogno delle importazioni non utilizzate (addeditedir, dirname, abspath)? O sono rimasti da una versione precedente di questa risposta? –

+1

La modifica di sys.path è una cattiva idea. https://youtu.be/bAcfPzxB3dk?t=233 –

9

non so il motivo per cui la risposta precedente ha -1 a parte forse alcune linee ridondanti che possono essere corrette. Ad ogni modo, ho trovato un metodo leggermente diverso che non comporta l'aggiunta di nulla al percorso Python.

Questa è la mia struttura di directory finale, vi spiegherò in un momento:

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 

Non importa se avete appena creato il vostro progetto o se si desidera spostare le applicazioni, creare la apps sottodirectory che dovrebbe contenere le tue app. Il trucco è aggiungere un __init__.py a quella directory.

mkdir apps 
touch apps/__init__.py 

Ora è possibile spostare le applicazioni esistenti nel apps sottodirectory. Se si desidera creare uno nuovo, invece qui ci sono i comandi:

python manage.py mysecondapp 
mv mysecondapp apps/ 

Avvertenza: non essere tentati di chiamare python manage.py ./apps/mysecondapp. Per qualche motivo questo elimina tutte le altre app in quella directory. Ho appena perso una giornata di lavoro in questo modo.

Successivamente, sarà necessario correggere alcune importazioni.Il tuo settings.py devono avere il prefisso apps:

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

Infine, fissare del urls.py progetto come prefisso apps:

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

A seconda di come li hai scritto, si potrebbe anche avere a fissare un paio di importazioni all'interno della vostra app. O semplicemente usa from models import MyFirstModel o anche prefisso usando from apps.myfirstapp.models import MyFirstModel.

In breve, se si crea la propria directory apps in python (aggiungendo __init__.py), è possibile utilizzarla come parte del percorso di importazione. Questo dovrebbe funzionare indipendentemente dal metodo di distribuzione senza configurazione aggiuntiva.

+0

Mi sono imbattuto in un problema che non è stato risolto in questa risposta, in quanto urls.py in apps/myfirstapp doveva avere il primo argomento di pattern (...) impostato su "apps.myfirstapp", come prima che lo spostassi, leggeva solo "myfirstapp". L'output di debug di Django è stato molto meno utile per questo. – Ethereal

+1

da apps.myfirstapp.models importare MyFirstModel non funziona nei file secondapps file..don non so perché .. – tyan

0

@Radu Gheorghiu's answer; Non è necessario modificare settings.py e la linea path insert può essere condensata su 1 riga di codice.

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

ho sourced questa risposta da http://obroll.com/nested-application-inside-apps-sub-folder-in-django-1-3/

+0

Si prega di non creare una risposta su una risposta. Se vuoi aggiungere qualcosa alla risposta di Radu, usa la funzione di commento. – Silicomancer

1

Usa BASE_DIR variabile dal settings.py. Dovrebbe essere già definito:

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

Meglio non utilizzare l'attributo __file__ in manage.py e wsgi.py, in quanto si trovano in diverse directory.

Quindi, basta aggiungere il seguente al manage.py e wsgi.py (e al celery.py se si utilizza sedano):

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

Vi ritroverete con la seguente struttura del progetto:

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