Perché DEBUG = False setting non riesce ad accedere al mio file statico django?


356

Sto costruendo un'app usando Django come cavallo di battaglia. Finora tutto è andato bene - impostazioni db specificate, directory statiche configurate, URL, viste ecc. Ma i problemi sono iniziati di nascosto nel momento in cui volevo renderizzare le mie bellissime e personalizzate pagine 404.html e 500.html.

Ho letto i documenti sulla gestione degli errori personalizzati e impostato le configurazioni necessarie in UrlsConf, creato viste corrispondenti e aggiunto 404.html e 500.html alla directory dei modelli della mia app (specificata anche in settings.py).

Ma i documenti dicono you can actually view custom error views until Debug is Off, quindi l'ho disattivato per testare le mie cose, ed è allora che le cose vanno impazzite!

Non solo non riesco a visualizzare il 404.html personalizzato (in realtà, si carica, ma poiché le mie pagine di errore contengono ciascuna un messaggio di errore grafico, come una bella immagine), viene caricata l'origine della pagina di errore, ma non viene caricato nient'altro! Neanche CSS o Javascript collegati!

Generalmente, una volta impostato DEBUG = False, verranno caricate tutte le visualizzazioni, ma i contenuti collegati (CSS, Javascript, Immagini, ecc.) Non verranno caricati! Cosa sta succedendo? Manca qualcosa che riguarda i file statici e l' DEBUGimpostazione?


Come stai ospitando? Macchina locale con il server di prova?
j_syk,

macchina locale con server di prova. Fondamentalmente voglio vedere come la mia gestione personalizzata degli errori funzionerebbe simulando localmente scenari come l'accesso a pagine inesistenti e causare errori di runtime, ma il mio contenuto statico non verrà caricato.
nemesisfixx,

O può essere fatto a livello di server come qui o può essere gestito a livello di Django aggiungendo urlpattern. Ho trovato questa domanda qui sotto per lo stesso problema. stackoverflow.com/questions/6405173/…
Pankaj Anand

Risposte:


353

Con il debug disattivato Django non gestirà più i file statici per te: il tuo server di produzione (Apache o qualcosa del genere) dovrebbe occuparsene.


3
Questo in realtà risolve la mia curiosità, quindi ora ha senso, e posso davvero occuparmene con Apache, se necessario, allora. Avevo pensato che fosse un problema con le mie impostazioni. Grazie
nemesisfixx il

5
Ho trovato questa risposta molto utile. Nel caso in cui qualcun altro si trovi nella mia stessa situazione (utilizzando Google App Engine per l'app con nonrel django): non dimenticare di aggiornare app.yaml.
Lyndsey Ferguson,

3
gestori: - url: / static static_dir: static
Lyndsey Ferguson

475

Se hai ancora bisogno di server statici localmente (es. Per test senza debug) puoi eseguire devserver in modalità non sicura:

manage.py runserver --insecure

6
Mentre questo flag funziona, non serve il contenuto della cartella
collectstatic

5
Questa è magia. Grazie signore, sei un eroe. Questa risposta dovrebbe essere unita alla risposta accettata in quanto risolve il problema senza dover servire l'elettricità statica in un modo diverso da quello di django stesso.
Depado,

1
Questo era tutto ciò di cui avevo bisogno. Sebbene la migliore pratica sarebbe quella di utilizzare la variabile di ambiente per distinguere tra ambiente di sviluppo e produzione e interruttore di debug.
Neeraj Gupta,

1
Nota: NON funzionerà con ManifestStaticFilesStorage come code.djangoproject.com/ticket/19295
Andrea Rabbaglietti,

9
qualcuno può dirmi se ciò che è così insicuro al riguardo
Kavi Vaidya,

36

È possibile utilizzare WhiteNoise per servire file statici in produzione.

Installare:

pip install WhiteNoise

E cambia il tuo file wsgi.py in questo:

from django.core.wsgi import get_wsgi_application
from whitenoise.django import DjangoWhiteNoise

application = get_wsgi_application()
application = DjangoWhiteNoise(application)

E sei a posto!

Ringraziamo Blog Creativo Manubrio .

MA, in realtà non è consigliabile servire file statici in questo modo durante la produzione. Il tuo server di produzione (come nginx) dovrebbe occuparsene.


1
Sembra interessante, ma non ha funzionato per me semplicemente aggiungendo quella linea al wgsi.pyfile. La documentazione che hai collegato sembra fornire altre istruzioni per l'uso di WhiteNoise. Proverò in altri modi e ti aggiornerà qui.
DarkCygnus,

+1 poiché questo è stato ciò che alla fine mi ha portato alla soluzione. Ho aggiunto una risposta in cui ho incluso i passaggi aggiuntivi che ho fatto per farlo effettivamente funzionare.
DarkCygnus,

manage.py runserver --insecurenon ha funzionato per me. Questo lo fa, però.
Jee,

3
Si noti che con WhiteNoise versione 4.0, la configurazione è cambiata. Non aggiungere queste righe a wsgi.py. Invece, basta aggiungere 'whitenoise.middleware.WhiteNoiseMiddleware'al middleware. Vedi le note di rilascio del log delle modifiche
Doug Harris,

Perché * non è raccomandato? Lo uso da anni in diversi siti, funziona benissimo. Anche Heroku lo usa nel loro modello Django.
Omar Gonzalez,

33

In urls.py ho aggiunto questa riga:

from django.views.static import serve 

aggiungi questi due URL in urlpatterns:

url(r'^media/(?P<path>.*)$', serve,{'document_root': settings.MEDIA_ROOT}), 
url(r'^static/(?P<path>.*)$', serve,{'document_root': settings.STATIC_ROOT}), 

e sia i file statici che quelli multimediali erano accessibili quando DEBUG = FALSE.
Spero che sia d'aiuto :)


Quando ha fatto il pannello di amministrazione css non si carica ??
Thusitha Deepal,

Sì. L'unico che funziona !! Grazie.
DrGeneral,

ECCEZIONALE! Non dimenticare di impostare STATIC_ROOT e manage.py collectstatic.
Domingo R

2
Oggi sostituisci url(conre_path(
Leopd

19

Se si utilizza la vista del servizio statico in fase di sviluppo, è necessario disporre di DEBUG = True:

avvertimento

Funzionerà solo se DEBUG è True.

Questo perché questa visione è gravemente inefficiente e probabilmente insicura. Questo è destinato esclusivamente allo sviluppo locale e non dovrebbe mai essere utilizzato in produzione.

Documenti: servire file statici in via di sviluppo

EDIT: potresti aggiungere alcuni URL solo per testare i tuoi modelli 404 e 500, basta usare la vista generica direct_to_template nei tuoi URL.

from django.views.generic.simple import direct_to_template

urlpatterns = patterns('',
    ('^404testing/$', direct_to_template, {'template': '404.html'})
)

1
Come si fa, quindi servire i file statici in produzione? NVM, l'ho appena visto. Grazie.

dovresti impostare il tuo server web per ospitare una directory specifica. Più comunemente useresti Apache o Nginx. I documenti ci entrano un po '.
j_syk,

grazie @j_syk, avevo già provato questo approccio di visualizzazione di 404.html e 500.html tramite altri meccanismi non di errore simili a quelli che suggerisci. Ma volevo sapere se era assolutamente impossibile che le mie pagine venissero visualizzate correttamente come avrebbero fatto in produzione, pur continuando a essere in esecuzione sul mio server di test: la delega della gestione dei file statici ad Apache quando Debug è Off lo regola per me. Grazie per aver contribuito.
nemesisfixx,

@mcnemesis Non sono sicuro di cosa accadrà, ma prova a impostare TEMPLATE_DEBUG = False e DEBUG = True. Se disattivi i graziosi errori, non sono sicuro che vada invece ai modelli
404/500

come previsto, farlo non ha prodotto risultati positivi, ma grazie ancora.
nemesisfixx,

17

La risposta di Johnny è ottima, ma ancora non ha funzionato per me semplicemente aggiungendo quelle righe descritte lì. Sulla base di quella risposta, i passaggi che hanno funzionato per me dove:

  1. Installa WhiteNoise come descritto:

    pip install WhiteNoise
  2. Crea la STATIC_ROOTvariabile e aggiungi WhiteNoise alla tua MIDDLEWAREvariabile in settings.py:

    #settings.py
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'whitenoise.middleware.WhiteNoiseMiddleware', #add whitenoise
        'django.contrib.sessions.middleware.SessionMiddleware',
        ...
    ]
    
    #...
    
    STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') ##specify static root
  3. Quindi, modifica il tuo wsgi.pyfile come spiegato nella risposta di Johnny:

    #wsgi.py
    from django.core.wsgi import get_wsgi_application
    from whitenoise.django import DjangoWhiteNoise
    
    application = get_wsgi_application()
    application = DjangoWhiteNoise(application)
  4. Successivamente, distribuisci le modifiche sul tuo server (con git o qualunque cosa tu usi).

  5. Infine, esegui l' collectstaticopzione dal manage.pytuo server. Questo copierà tutti i file dalle tue cartelle statiche nella STATIC_ROOTdirectory che abbiamo specificato prima:

    $ python manage.py collectstatic

    Ora vedrai una nuova cartella denominata staticfilesche contiene tali elementi.

Dopo aver seguito questi passaggi ora puoi eseguire il tuo server e sarai in grado di vedere i tuoi file statici mentre sei in modalità Produzione.

Aggiornamento: nel caso in cui tu avessi la versione <4 il log delle modifiche indica che non è più necessario dichiarare il WSGI_APPLICATION = 'projectName.wsgi.application'tuo settings.pyfile.


L'ho fatto di conseguenza, e sullo sviluppo ha funzionato bene, ma non in produzione. Ha ancora lo stesso problema quando DEBUG == False
Anna Huang,

@AnnaHuang Cosa intendi per sviluppo e produzione? Hai ambienti o macchine separati? Sono configurati allo stesso modo?
DarkCygnus,

13

In realtà puoi pubblicare file statici in un'app Django di produzione, in modo sicuro e senza DEBUG=True.

Invece di usare Django stesso, usa dj_static nel tuo file WSGI ( github ):

# requirements.txt:

...
dj-static==0.0.6


# YOURAPP/settings.py:

...
STATIC_ROOT = 'staticdir'
STATIC_URL = '/staticpath/'

# YOURAPP/wsgi.py:

...
from django.core.wsgi import get_wsgi_application
from dj_static import Cling

application = Cling(get_wsgi_application())

2
Da allora ho scoperto il whitenoise , che potrebbe essere più completo.
Robin Winslow,

7

Apri il tuo progetto urls.py, quindi trova questa istruzione if.

if settings.DEBUG:
    urlpatterns += patterns(
        'django.views.static',
        (r'^media/(?P<path>.*)','serve',{'document_root': settings.MEDIA_ROOT}), )

Puoi modificare le impostazioni.DEBUG su True e funzionerà sempre. Ma se il tuo progetto è qualcosa di serio, dovresti pensare ad altre soluzioni sopra menzionate.

if True:
    urlpatterns += patterns(
        'django.views.static',
        (r'^media/(?P<path>.*)','serve',{'document_root': settings.MEDIA_ROOT}), )

In django 1.10 puoi scrivere così:

urlpatterns += [ url(r'^media/(?P<path>.*)$', serve, { 'document_root': settings.MEDIA_ROOT, }), url(r'^static/(?P<path>.*)$', serve, { 'document_root': settings.STATIC_ROOT }), ]

3
Il tuo codice è corretto, ma in Django 1.10, la configurazione è per media e static è: urlpatterns + = [url (r '^ media / (? P <path>. *) $', Serve, {'document_root': settings .MEDIA_ROOT,}), url (r '^ static / (? P <percorso>. *) $', Serve, {'document_root': settings.STATIC_ROOT}),]
Roberth Solís

6

È possibile eseguire il debug in molti modi diversi. Ecco il mio approccio.

localsettings.py:

DEBUG = False
DEBUG404 = True

urls.py:

from django.conf import settings
import os

if settings.DEBUG404:
    urlpatterns += patterns('',
        (r'^static/(?P<path>.*)$', 'django.views.static.serve',
         {'document_root': os.path.join(os.path.dirname(__file__), 'static')} ),
    )

Assicurati di leggere i documenti;)

https://docs.djangoproject.com/en/2.0/howto/static-files/#limiting-use-to-debug-true


0

Il supporto per gli argomenti di visualizzazione stringa a url () è obsoleto e verrà rimosso in Django 1.10

La mia soluzione è solo una piccola correzione alla soluzione Conrado sopra.

from django.conf import settings
import os
from django.views.static import serve as staticserve

if settings.DEBUG404:
    urlpatterns += patterns('',
        (r'^static/(?P<path>.*)$', staticserve,
            {'document_root': os.path.join(os.path.dirname(__file__), 'static')} ),
        )

0

Anche se non è più sicuro, ma è possibile modificare il codice sorgente. navigare versoPython/2.7/site-packages/django/conf/urls/static.py

Quindi modifica come segue:

if settings.DEBUG or (prefix and '://' in prefix):

Quindi, se settings.debug==Falsenon ha effetto sul codice, anche dopo l'esecuzione provare python manage.py runserver --runservera eseguire file statici.

NOTA : le informazioni devono essere utilizzate solo a scopo di test


0

Ho apportato le seguenti modifiche al mio progetto / urls.py e ha funzionato per me

Aggiungi questa riga: da django.conf.urls import url

e aggiungi: url (r '^ media / (? P. *) $', serve, {'document_root': settings.MEDIA_ROOT,}), in urlpatterns.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.