TEMPLATE_DIRS

Django, Flask, Bottle, WSGI, CGI…
Antworten
jayx
User
Beiträge: 9
Registriert: Donnerstag 13. Dezember 2012, 18:28

hi,

ich habe hier einen Server mit CentOS, FCGI, Python2.7, Django und Flup

Ich habe ein Project names MyDjangoProject und eine app namens poll laut der offiziellen Anleitung erstellt.
Der Admin Bereich, die Polls und Choices funktionieren soweit bis zu dem Punkt an dem ich die templates einfügen soll, welche den admin Bereich anders aussehen lassen sollen. Der Code dafür ist auch vorgegeben.

1. Wo genau soll ich/man denn den Templates ordner anlegen

Verzeichnisstruktur:

/home/
unterordner/
project/
(templates)?
/app/
(templates)?
innerhalb des template ordners soll man auch einen admin ordner anlegen der eine base-site.html beinhaltet(von lib/python/django/contrib/admin/usw.)

2.

Wie genau soll ich den Path zu dem Template Ordner angeben?

Code: Alles auswählen

TEMPLATE_DIRS = ("/home/project/templates")
TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'),)
TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), 'templates')
und was genau bedeutet BASE_DIR oder SITE_ROOT, sind das Platzhalter oder bewirken die irgendwas?



Das Admin Interface läuft, aber sobald ich die TEMPLATE_DIRS verändere, egal wie, kommt 500 INTERNAL SERVER ERROR, obwohl debug = True ;/


danke
jayx
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo jayx,

die settings.py ist eine ganz normale Python-Datei. Das heißt also, die Konstanten werden auch sofort ausgewertet,
wenn also BASE_DIR einen bestimmten Wert beim setzen von TEMPLATE_DIRS hat, ist das fix.
Ich persönlich benutze die dritte Variante, wobei Du darauf achten solltest, dass TEMPLATE_DIRS eine Liste/Tuple ist.

Code: Alles auswählen

BASE_DIR = os.path.join(os.path.dirname(__file__), '..')

TEMPLATE_DIRS = ("/home/project/templates", )
TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'), )
TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), '..', 'templates'), )
Die erste Variante ist für meinen Geschmack zu unflexibel.

Zum INTERNAL SERVER ERROR braucht's noch a biserl mehr Information.
jayx
User
Beiträge: 9
Registriert: Donnerstag 13. Dezember 2012, 18:28

Danke für die schnelle Antwort.

Wenn das

Code: Alles auswählen

BASE_DIR = os.path.join(os.path.dirname(__file__), '..')
deine art ist wie definierst du dann die TEMPLATE_DIRS konkret?

Code: Alles auswählen

TEMPLATE_DIRS = (os.path.join(os.path.join(__base-site.html__), '..')
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Entschuldige, aber ich versteh die Frage nicht.
os.path.dirname(__file__) ist ja der Pfad in der settings.py liegt. Im übergeordneten
Verzeichnis liegen dann normalerweise die globalen template/static usw.

Was soll __base-site.html__ sein?
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Sirius3 hat geschrieben:Was soll __base-site.html__ sein?
Ich denke mal, er ist davon ausgegangen, dass "__file__" in deinem Beispiel für einen beliebigen Dateinamen steht. ;)

Mir schwahnt, dass er OP nicht wirklich viele Python-Kenntnisse hat...
BlackJack

Sirius3 hat geschrieben:Was soll __base-site.html__ sein?
Das ist eine Subtraktion — es wird das `html__`-Attribut vom `site`-Objekt von `__base` abgezogen. SCNR. :mrgreen:
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

snafu hat geschrieben:Ich denke mal, er ist davon ausgegangen, dass "__file__" in deinem Beispiel für einen beliebigen Dateinamen steht. ;)
Dann sollten wir doch mal Aufklärungsarbeit betreiben.

Bei Modulen gilt Folgendes: "[...] __file__ is the pathname of the file from which the module was loaded [...]". (Referenz: http://docs.python.org/2/reference/datamodel.html)
jayx
User
Beiträge: 9
Registriert: Donnerstag 13. Dezember 2012, 18:28

Danke erstemal für die Antworten.

Warum aber gibt die Comments dann sowas
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
an

wenn

Code: Alles auswählen

TEMPLATE_DIRS = (
   #'/home/mydjangoproject/templates',
    )
dann nicht funktioniert

snafu hat geschrieben:
Sirius3 hat geschrieben:Was soll __base-site.html__ sein?
Ich denke mal, er ist davon ausgegangen, dass "__file__" in deinem Beispiel für einen beliebigen Dateinamen steht. ;)

Mir schwahnt, dass er OP nicht wirklich viele Python-Kenntnisse hat...
dir schwahnt richtig, deswegen wende ich mich auch an euch, weil es durch lesen + try and error nicht mehr funktioniert hat und ich mir ebenso dachte dass evtl das verständnis an der Sache auch dienlich sein könnte...

Kann mir denn einer mal ein Konkretes Beispiel anhand meiner Ordner Sturktur geben. Bzw mir sagen warum denn /home/mydjangoproject/templates, falsch ist.


Danke
BlackJack

@jayx: Also zum einen ist die Zeile mit dem Pfad in Deinem Beitrag auskommentiert, und dann muss dieser Pfad auch existieren und Templates enthalten. Gibt es bei Dir tatsächlich einen Benutzer `mydjangoprojects` beziehungsweise ein solches Verzeichnis? Darf der Benutzer unter dem Django läuft, darauf zugreifen?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

jayx hat geschrieben:Warum aber gibt die Comments dann sowas
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
an
wenn

Code: Alles auswählen

TEMPLATE_DIRS = (
   #'/home/mydjangoproject/templates',
    )
dann nicht funktioniert
Das funktioniert nicht weil die Zeile auskommentiert ist. Wenn du die Zeile wieder aktivierst, dann wird es gehen. Allerdings setzt das dann voraus, dass dein Verzeichnis wirklich exakt /home/mydjangoproject/templates ist. Verschiebst du das Projekt in einen anderen Ordner, dann musst du zwangsweise die Settings anpassen. Mit dem vorgestellten dynamischen Ansatz ist das nicht erforderlich.

In allen meinen Django-Settings ermittele ich zuerst einmal den Basis-Pfad der Anwendung. Dazu ermittele ich den aktuellen Pfad der settings.py (os.path.dirname(__file__)), bewege mich dann eine Ebene nach oben (os.path.join([...], '..') und hübsche den Pfad dann auf (os.path.realpath).

Code: Alles auswählen

BASE_PATH = os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))
Darauf kann ich dann später an diversen Stellen aufbauen. Bei den Settings für die Templates sieht das dann so aus.

Code: Alles auswählen

TEMPLATE_DIRS = (
    os.path.join(BASE_PATH, 'templates').replace('\\', '/'),
    )
Wenn ich den Code dann an einem anderen Computer bearbeite und ausführe ist es völlig egal in welchem Pfad er liegt und ob es sich um ein Linux- oder Windows-System handelt. Es läuft einfach.
jayx
User
Beiträge: 9
Registriert: Donnerstag 13. Dezember 2012, 18:28

Ah /me, danke für die ausführlicher Erklärung.

dass mein pfad kommentiert war, war nur ein kopierfehler. Natürlich war die #davor weg und es gibts den ordner auch und er hat auch templates enthalten. Ebenfalls ist Zugriff auf den Pfad gewährt.

BASE_PATH ermittelt also mit os.path.dirname den Pfad in dem die settings.py liegt, richtig? mit os.path.join wechsel ich dann in ein verzeichnis weiter nach oben zb. von home/xx/project nach home/xx/ wo dann auch mein templates ordner liegen soll?

das mit dem realpath is wahrscheilich optional? zumindest verstehe ich den sinn dahinter nicht wirklich.

und BASE_PATH kommt auch in die settings.py rein?
BlackJack

@jayx: `os.path.join()` wechselt keine Verzeichnisse sondern verbindet Pfadangaben. Und `realpath()` ist *nicht* optional, denn es sollen ja *absolute* Pfade verwendet werden, ohne irgendwelche relative Angaben wie '/../'. Die Frage ist auch ob `__file__` absolut oder relativ ist. Das ist AFAIK nicht spezifiziert, es kann also beides vorkommen.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

jayx hat geschrieben:BASE_PATH ermittelt also mit os.path.dirname den Pfad in dem die settings.py liegt, richtig?
Das ist korrekt. Den kompletten Pfad inklusive Dateinamen finde ich in __file__. dirname liefert dann den Teil ohne die Dateikomponente.
jayx hat geschrieben:mit os.path.join wechsel ich dann in ein verzeichnis weiter nach oben zb. von home/xx/project nach home/xx/ wo dann auch mein templates ordner liegen soll?
Mit os.path.join füge ich auf intelligente Art und Weise Pfadbestandteile für das Dateisystem zusammen. Im Endeffekt ist das aber reine Stringverkettung, real gewechselt im Dateisystem wird da nichts. Der zu ergänzende Pfadbestandteil wurde von mir mit '..' angegeben und diese zwei Punkte stehen auf jedem von mir produktiv verwendeten Dateisystem für die nächsthöhere Ebene.
jayx hat geschrieben:das mit dem realpath is wahrscheilich optional? zumindest verstehe ich den sinn dahinter nicht wirklich.
Ich liefere mal ein Besipiel. Das von mir importierte Modul hat folgenden Inhalt.

Code: Alles auswählen

import os

print __file__
print os.path.dirname(__file__)
print os.path.join(os.path.dirname(__file__), '..')
print os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))
Als Ergebnis bekomme ich

Code: Alles auswählen

/home/matthias/p/sub/mod.pyc
/home/matthias/p/sub
/home/matthias/p/sub/..
/home/matthias/p
Der Pfad sieht nach der Verwendung von realpath einfach sauberer aus. Bei einer anschließenden Verkettung mit einem Unterordner templates bekomme ich dadurch /home/matthias/p/templates und nicht /home/matthias/p/sub/../templates.
jayx hat geschrieben:und BASE_PATH kommt auch in die settings.py rein?
Na ja, wo soll es sonst hin. Schließlich orientiere ich mich ja explizit an der Position der settings.py im Dateisystem und die kann ich aus der Datei selber am besten ermitteln. Die settings.py mag magisch wirken, aber im Endeffekt enthält sie ganz normales Python und ich kann dort tun und lassen was ich möchte. Wenn ich dann auch noch sinnvolle Dinge tue wie in diesem Fall, dann ist es umso besser.
BlackJack

@/me: Wenn Du es portabler haben möchtest, könntest Du statt '..' einfach `os.pardir` verwenden. :-)
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

BlackJack hat geschrieben:@/me: Wenn Du es portabler haben möchtest, könntest Du statt '..' einfach `os.pardir` verwenden. :-)
Pfff, das kann ja jeder. :mrgreen:

Ehrlich gesagt war mir das gar nicht mehr geläufig. Ich werde den Code aber tatsächlich umstellen.
Antworten