Was ist der Sinn von Djangos Collectstatic?

86

Dies ist wahrscheinlich eine dumme Frage, aber es klickt einfach nicht in meinem Kopf.

In Django besteht die Konvention darin, alle Ihre statischen Dateien (z. B. CSS, JS), die für Ihre App spezifisch sind, in einem Ordner namens " Statisch" abzulegen . Die Struktur würde also so aussehen:

mysite/
    manage.py
    mysite/ --> (settings.py, etc)
    myapp/ --> (models.py, views.py, etc)
        static/

In habe mysite/settings.pyich:

STATIC_ROOT = 'staticfiles'

Also, wenn ich den Befehl ausführe:

python manage.py collectstatic   

Es wird ein Ordner erstellt, der staticfilesauf der Stammebene aufgerufen wird (also dasselbe Verzeichnis wie myapp/).

Was ist der Sinn davon? Erstellt es nicht nur eine Kopie aller meiner statischen Dateien?

Chris Tang
quelle

Antworten:

69

Sammeln Sie statische Dateien aus mehreren Apps in einem einzigen Pfad

Nun, ein einzelnes Django Projekt mehrere verwenden können Apps , also , während es nur eine haben myapp, kann es tatsächlich sein myapp1, myapp2usw.

Indem Sie sie aus den einzelnen Apps in einen einzelnen Ordner kopieren, können Sie Ihren Frontend-Webserver (z. B. nginx) auf diesen einzelnen Ordner verweisen STATIC_ROOTund statische Dateien von einem einzigen Speicherort aus bereitstellen, anstatt Ihren Webserver so zu konfigurieren, dass statische Dateien aus mehreren Pfaden bereitgestellt werden .

Persistente URLs mit ManifestStaticFilesStorage

Ein Hinweis zum Anhängen des MD5-Hashs an den Dateinamen zur Versionierung: Dies ist nicht Teil des Standardverhaltens von collectstatic, wie settings.STATICFILES_STORAGEstandardmäßig StaticFilesStorage(was dies nicht tut).

Der MD5-Hash wird aktiviert, z. B. wenn Sie ihn für die Verwendung festlegen ManifestStaticFilesStorage, wodurch dieses Verhalten angezeigt wird.

Der Zweck dieses Speichers besteht darin, die alten Dateien weiterhin bereitzustellen, falls einige Seiten noch auf diese Dateien verweisen, z. B. weil sie von Ihnen oder einem Proxyserver eines Drittanbieters zwischengespeichert werden. Darüber hinaus ist es sehr hilfreich, wenn Sie Expires-Header für die Zukunft auf die bereitgestellten Dateien anwenden möchten, um die Ladezeit für nachfolgende Seitenbesuche zu beschleunigen.

Bakkal
quelle
2
Sie möchten sagen, dass es leicht zu finden sein wird, dass der Webserver den statischen Inhalt
bereitstellt
44

Statische Django-Dateien können sich an vielen Stellen befinden. Eine Datei, die so bereitgestellt wird, wie sie von vielen Orten stammen/static/img/icon.png könnte . Standardmäßig:

  • FileSystemFinderwird img/icon.pngin jedem von suchen STATICFILES_DIRS,
  • AppDirectoriesFinderwird img/icon.pngim staticUnterordner in jedem Ihrer suchen INSTALLED_APPS. Auf diese Weise können Bibliotheken wie Django Admin Ihrer App eigene statische Dateien hinzufügen.

Jetzt: Dies funktioniert nur, wenn Sie manage.py runservermit DEBUG = 1 ausführen . Wenn Sie live gehen, werden die statischen Assets vom Django-Prozess nicht mehr bereitgestellt. Es wäre ineffizient, Django zu verwenden, um diese zu bedienen. Es gibt speziellere Tools dafür.

Stattdessen sollten Sie Folgendes tun:

  • Finden Sie alle statischen Dateien aus jeder App
  • Erstellen Sie ein einzelnes Verzeichnis, das alle enthält
  • Laden Sie sie irgendwo hoch ( staticirgendwo auf Ihrem Webserver oder in einem Dateispeicher eines Drittanbieters)
  • Konfigurieren Sie Ihren Webserver (z. B. nginx) so, dass er /static/*direkt aus diesem Verzeichnis bereitgestellt wird, und leiten Sie alle anderen Anforderungen an Django weiter.

collectstatic ist ein vorgefertigtes Skript, das dieses Verzeichnis für Sie vorbereitet, sodass Sie es direkt mit Ihrem Bereitstellungsskript verbinden können.

Kos
quelle
25

In der Produktionsinstallation möchten Sie dauerhafte URLs haben. Die URL ändert sich nur, wenn sich der Dateiinhalt ändert.

Dies soll verhindern, dass Clients beim Öffnen einer Webseite von Django aus eine falsche Version der CSS- oder JS-Datei auf ihrem Computer haben. Django staticfiles erkennt Dateiänderungen und aktualisiert URLs entsprechend, sodass der Webbrowser bei Änderungen der CSS- oder JS-Datei die neue Version herunterlädt.

Dies wird normalerweise erreicht, indem dem Dateinamen während des collectstaticLaufs MD5-Hash hinzugefügt wird.

Bearbeiten: Siehe auch die zugehörige Antwort auf mehrere Apps.

Mikko Ohtamaa
quelle
1
Gut! wusste es nicht
Doniyor
"Wird normalerweise durch Hinzufügen von MD5-Hash erreicht", meinen Sie ManifestStaticFilesStorage ? Schön, das habe ich nicht gesehen
Kos
3
Ich denke, dass standardmäßig kein MD5-Hashing stattfindet, da settings.STATICFILES_STORAGEstandardmäßig "H5" aktiviert ist. StaticFilesStorageDer MD5 wird also erst aktiviert, nachdem Sie ihn z. B. auf " ManifestStaticFilesStorageRichtig" gesetzt haben. Stimmt das?
Bakkal
@MikkoOhtamaa Aber woher weiß die Frontend-App dann, mit welchem ​​Dateinamen sie verknüpft werden soll, da sich dieser immer ändert?
Lapin
@ lapin Gute Frage! Natürlich muss es 1) eine Zuordnung zu den neuesten Versionen und 2) eine Möglichkeit geben, dies zu kommunizieren. Normalerweise wird es irgendwo in einer Datei gespeichert. Wenn Sie dann nach der vollständigen URL für die neueste Version von X fragen, erhalten Sie ein Ergebnis.
Mikko Ohtamaa
9

Dies ist nützlich, wenn die Website mehrere Django-Apps enthält.

collectstatic sammelt dann statische Dateien von allen Apps an einem Ort - damit sie in einer Produktionsumgebung bereitgestellt werden können.

aa333
quelle