2010-01-14 28 views
13

Background:In che modo le app Django raggruppano i supporti statici?

sto iniziando a utilizzare Django per la prima volta, che è anche la mia prima incursione in sviluppo web. Sono rimasto bloccato su tutto il problema del "servizio di supporti statici". Dopo aver passato un po 'di tempo a esaminare tutte le domande di documentazione e StackOverflow, penso di capire come dovrebbe funzionare (ad esempio MEDIA_ROOT, MEDIA_URL, aggiornamento del file urls, ecc.).

mia domanda:

Ok, quindi ecco la parte che non sono sicuro. Le applicazioni di Django dovrebbero essere "collegabili", cioè posso spostare un'applicazione da un progetto a un altro. Quindi, come dovrebbero queste applicazioni raggruppare i supporti statici?

Ad esempio, supponiamo di avere un'applicazione "foo", che dispone di modelli che caricano alcuni file css/immagine. Dove dovrei mettere questi file, in modo che vengano automaticamente pubblicati una volta che includo l'applicazione?

L'unica soluzione che vedo è che l'installazione di un'applicazione deve includere la fase aggiuntiva di copiare il suo supporto statico in un punto del proprio server che serve quel supporto.

È questo il modo accettato per farlo? Include un passo in più, ma forse è normale quando si tratta di web-dev (sono nuovo, quindi non lo so).

Inoltre, se questo è il modo, c'è un modo standard per raccogliere tutti i miei supporti statici per rendere più facile sapere cosa devo servire? (Ad esempio, è standard avere una cartella denominata "media" o qualcosa all'interno dell'app?).

Grazie,

risposta

9

Convenzione è quello di mettere i media statici sia in media/appname/o statico/appname/all'interno della app (simile ai modelli).

Per utilizzare le app del progetto fornite con i supporti, si consiglia vivamente di utilizzare django-staticfiles. Servirà automaticamente i media (inclusi i media all'interno delle app) in fase di sviluppo attraverso una vista che sostituisce django.views.static.serve e viene fornito con un comando di gestione build_static che copierà i file multimediali da tutte le app in un'unica directory per la pubblicazione in produzione.

Aggiornamento: django-staticfiles ha become part of Django 1.3. Ora si aspetta che i media app vivano in una sottodirectory "statica /" dell'app, non in "media /". E il comando di gestione è ora "collectstatic".

+0

Questo è ora l'approccio corretto, come da Django 1.3. –

+1

Nota che https://github.com/jaddison/django-cachebuster/ fornisce un tag {% static%} molto utile per Django 1.3 – Eli

2

L'unica applicazione che conosco che si occupa di questo, senza alcun intervento è piuttosto meraviglioso django-debug-toolbar, anche se è discutibile che questo non è un grande esempio, dal momento che è un app specificamente progettato per la modalità di debug solo.

Il modo in cui si tratta di esso è che serve i suoi media attraverso Django per sé - vedi la fonte per urls.py:

url(r'^%s/m/(.*)$' % _PREFIX, 'debug_toolbar.views.debug_media'), 

In generale, questa è una cattiva idea (non si vuole servire statica file attraverso Django), per this comment from the documentation:

[Serving file statici tramite Django] è inefficiente e insicuro . Non utilizzare questo in un'impostazione di produzione . Utilizzare questo solo per lo sviluppo .

Ovviamente, la barra degli strumenti django-debug viene utilizzata solo per lo sviluppo, quindi penso che il suo metodo di implementazione abbia senso, ma questa è un'eccezione.

In generale, il modo migliore che conosco per farlo è creare collegamenti simbolici ovunque il supporto sia memorizzato sul supporto all'interno del codice dell'app. Ad esempio, crea una cartella denominata media all'interno della tua app, quindi richiedi agli utenti che installano l'app di aggiungere un collegamento simbolico dalla loro directory multimediale o di copiare il tutto.

+0

E come dovrei evitare di nominare scontri/fare riferimento ad esso nel mio codice? Se ho, per esempio, un'app "foo" con una cartella multimediale e un'app "bar" con una cartella multimediale, come faccio a fare riferimento alla cartella all'interno dei modelli dell'applicazione, senza causare problemi? –

+1

Se la tua app si chiama 'foobar', allora fai riferimento ai tuoi file multimediali usando' {{MEDIA_URL}} foobar/myawesomejs.js'. Richiedi ai tuoi utenti di impostare il link simbolico su 'foobar' all'interno della loro directory multimediale. –

+0

Penso che la mia risposta qui sotto (usando django-staticfiles) sia una soluzione a tutto tondo migliore; soprattutto dal momento che sembra che qualcosa basato su file statici possa essere incluso direttamente in Django 1.3. –

2

di solito inserisco le app multimediali./ Apps/appname/statici (le mie applicazioni risiede in una sottocartella app)

allora ho qualcosa di simile nel vhost in apache:

AliasMatch ^/apps/([^/]+)/static/(.*) /home/django/projectname/apps/$1/static/$2 
<DirectoryMatch "^/home/django/projectname/apps/([^/]+)/static/*"> 
     Order deny,allow 
     Options -Indexes 
     deny from all 
     Options +FollowSymLinks 
     <FilesMatch "\.(flv|gif|jpg|jpeg|png|ico|swf|js|css|pdf|txt|htm|html|json)$"> 
       allow from all 
     </FilesMatch> 
</DirectoryMatch> 

Ho anche questo nel mio urls.py per il server dev (utilizzare solo per il debug):

def statics_wrapper(request, **dict): 
    from django.views import static 
    return static.serve(request, dict['path'], document_root = os.path.join(settings.BASE_DIR, 'apps', dict['app'], 'static'), show_indexes=True) 
urlpatterns += patterns('', (r'^apps/(?P<app>[^/]+)/static/(?P<path>.+)$', statics_wrapper)) 

questo è molto utile perché statica URL vengono mappati semplicemente per filesystem, ad esempio:

http://wwww.ecample.com/apps/calendar/static/js/calendar.js risiede in [BASE_DIR]/apps/calend ar// static/js calendar.js

speranza che questo aiuta

Problemi correlati