2015-06-19 8 views
9

Sto usando Django 1.8 e voglio aggiungere un parametro ai miei file statici a cache bust.Cache che si rompe in Django 1.8?

Questo è quello che sto facendo in questo momento, l'impostazione di un parametro manuale:

<link href="{% static 'css/openprescribing.css' %}?q=0.1.1" rel="stylesheet"> 

ma ritengo ci deve essere un modo migliore per aggiornare il parametro.

Suppongo che sarebbe un po 'più ordinato avere un'impostazione passata attraverso il modello (e questo salverebbe doverlo aggiornare in più punti).

Ma quello che sarebbe veramente bello è se Django potesse aggiornarlo automaticamente per me.

Le note su django-cachebuster suggeriscono che è ora possibile farlo automaticamente in staticfiles, ma non riesco a trovare nulla nei documenti staticfiles su di esso.

Qualcuno conosce un modo per farlo?

+0

Che cosa esattamente vuoi ottenere? Caching? Se è così allora ci sono approcci migliori di quello che desideri realizzare. Se stai usando Django 1.8, in esecuzione con Nginx, ti suggerisco di lasciare che Nginx faccia la cache per te, mentre Django fa quello che sa fare meglio. – Rexford

+0

@Rexford Sto utilizzando Nginx, sì, con CloudFlare. Voglio mettere in cache bust (cioè gli utenti vedono automaticamente il nuovo file quando carico un nuovo file). Stai suggerendo che Nginx verrà automaticamente messo in cache per me? Se sì, puoi fornire dettagli? – Richard

+0

Vedere la mia risposta qui sotto, a patto che sia ciò che si desidera realizzare, ad esempio, vedere immediatamente qualsiasi contenuto appena caricato nuovamente, nginx offre tale funzionalità gratuitamente! Nessun django, nessun cache-busters potrebbe essere necessario. – Rexford

risposta

12

Sì, questo può essere fatto automaticamente con contrib.staticfiles. Esistono due ulteriori classi di archiviazione fornite che rinomineranno i file utilizzando un hash. Questi sono documentati qui: ManifestStaticFilesStorage e CachedStaticFilesStorage

Dalla documentazione:

una sottoclasse di backend di memorizzazione StaticFilesStorage che memorizza i nomi dei file che gestisce aggiungendo l'hash MD5 del contenuto del file al nome del file. Ad esempio, il file css/styles.css verrebbe salvato anche come css/styles.55e7cbb9ba48.css.

Lo scopo di questa memoria è di continuare a servire i vecchi file nel caso in cui alcune pagine si riferiscano ancora a tali file, ad es. perché sono memorizzati nella cache dall'utente o da un server proxy di terze parti. Inoltre, è molto utile se si desidera applicare future estensioni intestazioni Expires ai file distribuiti per accelerare il tempo di caricamento per le successive visite alle pagine.

La differenza principale è

CachedStaticFilesStorage è una classe simile come la classe ManifestStaticFilesStorage ma utilizza quadro di caching di Django per memorizzare i nomi di file hash trasformate al posto di un file manifesto statico chiamato staticfiles.json. Questo è utile soprattutto in situazioni in cui non si ha accesso al file system.

per consentire loro è necessario modificare l'impostazione STATICFILES_STORAGE è impostato su 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage' o 'django.contrib.staticfiles.storage.CachedStaticFilesStorage'. I nomi dei file vengono modificati solo quando DEBUG=False come sarebbe in produzione.

+0

Cosa succede se il file viene servito da un CDN? –

-1

Non sono esperto in Caching, ma penso che lasciare che nginx gestisca il caching potrebbe essere meglio che usare Django. Django ha molto da gestire, quindi puoi lasciare che il server statico leggero faccia quel brutto lavoro.

Non faccio uso di CloudFlare, ma io uso questa linea di memorizzare nella cache i miei statica, però, immediatamente il file modifiche, Nginx propaga il file più recente (che è lo stesso file):

location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { 
    expires 30d; 
    } 

che è un snippet from this gist Attualmente sto usando quella conf nella produzione , quindi so che funziona.

Una cosa che farò notare è, assicurarsi che MemCached non funzioni e sia collegato al django come back-end di cache. Dico questo, perché ho passato molte ore in passato a colpire la testa contro il muro, semplicemente perché MemCached memorizzava nella cache la mia pagina con ogni contenuto in esso per un massimo di 10 minuti.

con questa conf posizione nginx, Ogni volta che cambio il mio css, o caricare un nuovo file (statica), il nuovo file in carico subito, fino a quando ho python manage.py collectstatic 'li cato nella directory appropriata

Io sto per essere corretto, se questo non è in realtà la parte che fa il trucco.

La prova che sopra funziona con cache-busting (come la chiama lei)

  • sono andato al server
  • eliminato il mio cartella statica (nginx ancora in corso) sudo rm -rf static/
  • accede mio sito
  • Nessun caricamento statico
  • Torna indietro, e python manage.py collectstatic
  • Ho di nuovo accesso al mio sito. Statics loaded
  • Non è stato utilizzato alcun aggiornamento hardware del browser. No nginx reload | restart qualsiasi cosa sia stata usata.

Nginx è abbastanza intelligente da memorizzare le statiche nella cache, ma ricarica lo statico quando il file è nuovo e lo serve.

+1

Il problema con questa soluzione è che il browser ha ora memorizzato nella cache il file per 30d. Anche se nginx sa di servire nuovi, il browser non farà la richiesta. Il browser farà una nuova richiesta solo se l'url è cambiato, il che è ciò che l'hash nel nome del file raggiunge. – dalore

+0

Inoltre ho bisogno di memorizzare nella cache le cose che sto servendo da un CDN a volte, non servito dal mio server locale. Penso che funzionino entrambi, ma a volte è davvero necessario archiviare i modelli in Django. –

0

Ho appena creare un semplice tag che fa il trucco ....

import time 
from django import template 

register = template.Library() 

@register.simple_tag() 
def cache_bust(): 
    return int(time.time()) 

Poi nel modello solo fare qualcosa di simile ...

{% load cache_app %} 
<img src="/captcha/?cache_bust={% cache_bust %}" class="captcha"/> 

E avete busting della cache del modo semplice.

+1

Come comunità, se questa non è una buona risposta, possiamo ottenere un commento sul perché? Grazie! Sono qui per imparare tanto quanto condividere. –

Problemi correlati