Seite 1 von 1

Vermeiden von relativen URLs in Django-Templates möglich ?

Verfasst: Dienstag 19. Dezember 2006, 14:37
von midan23
Hallo allerseits,

am Schluss vom 3. Teil des Django-Tutorials wird beschrieben, wie man die URLconf der Applikation von der URLconf des Projekts trennt.

Geht so etwas auch in Templates ?

Ich würde in meinen Templates nur ungern relative Links verwenden müssen ... Absolute Links lassen sich besser mit der Liste in "urls.py" vergleichen ...

(Rein theoretisch müsste es gehen ... ich habe den Verdacht, das die "Admin"-Applikation genau das macht ...)

Verfasst: Dienstag 19. Dezember 2006, 17:56
von Leonidas
Klar, schreib ich deine Templates einfach

Code: Alles auswählen

<a href="http://dein.host.tld/django/irgendwas/">link</a>
statt relativer URLs. Ich mache es nicht, weil mir das etwas arg hardcoded scheint.

Verfasst: Dienstag 19. Dezember 2006, 18:15
von midan23
Nicht ganz was ich meinte ...

Ich habe im Projekt und in der Applikation eine "urls.py".
Die Applikations-"urls.py" wird in der Projekt-"urls.py" included.

Auf diese Art ist die Applikation etwas unabhängiger ...

Jetzt würde ich sowas gerne auch in den Templates der Applikation haben.

Statt

Code: Alles auswählen

<a href="/testapp/liste/">Übrsicht</a>
hätte ich dann so was wie

Code: Alles auswählen

<a href="{{base url }}liste/">Übersicht</a>

Verfasst: Donnerstag 21. Dezember 2006, 12:50
von concept!er
midan23 hat geschrieben: Statt

Code: Alles auswählen

<a href="/testapp/liste/">Übrsicht</a>
hätte ich dann so was wie

Code: Alles auswählen

<a href="{{base url }}liste/">Übersicht</a>
Hi midan23,

ja, das geht. Einfach einen Eintrag in deiner settings.py vornehmen, der auf deine Applikation zeigt, also so was wie

base_url = "myapp/"

In den Templates kannst du das dann als {{ settings.base_url }} ansprechen.

Schade, dass Django die Generierung solcher URLs nicht als Helper anbietet, das ist *imho* bei TurboGears und Pylons wesentlich eleganter gelöst.

Gruss, concept!er

Verfasst: Donnerstag 21. Dezember 2006, 15:27
von midan23
Dies URL-Geschichte ist schon etwas verwirrend ...
Einerseits sollen Django-Applikationen unabhängig sein, andererseits gibt es scheinbar keine einfache Möglichkeit, die URLs in Templates unabhängig zu machen (und relative URLs sind nicht immer nutzbar ...)
concept!er hat geschrieben: ja, das geht. Einfach einen Eintrag in deiner settings.py vornehmen, der auf deine Applikation zeigt, also so was wie

base_url = "myapp/"

In den Templates kannst du das dann als {{ settings.base_url }} ansprechen.
Irgend etwas scheine ich da übersehen zu haben ... "{{ settings.base_url }}" ist immer leer ...

Verfasst: Donnerstag 21. Dezember 2006, 22:22
von concept!er
midan23 hat geschrieben:Irgend etwas scheine ich da übersehen zu haben ... "{{ settings.base_url }}" ist immer leer ...
Oops :D hab ich doch glatt vergessen zu erwähnen: Du musst in deiner views.py in der entsprechenden View-Methode die Settings übergeben. Sieht ungefähr so aus:


from django.conf import settings

def index(request):
context=Context({'settings':settings, .... deine restlichen template-Variablen...})
return HttpResponse(template.render(context))

Damit sollte es dann gehen!

Verfasst: Donnerstag 21. Dezember 2006, 23:27
von midan23
Dann fällt diese Lösung flach (zu umständlich) ... in der "urls.py" der Applikation sind 13 Zeilen, und nur 5 davon verwenden Funktionen aus der "views.py" ... der Rest verwendet Generic Views.

Ich werd mich mal in Richtung "custom template tag" oder "middleware" umschauen ...

Irgendwie muss es doch gehen, ohne das man umständliche Verrenkungen machen muss ...

Verfasst: Freitag 22. Dezember 2006, 14:03
von midan23
Ich hab jetzt was, was seinen Zweck erfüllt ... Ist weder middleware noch ein custom template tag, sondern ein context processor:

Code: Alles auswählen

def application_base_url(request):
    from django.conf import settings
    urlconf = __import__(settings.ROOT_URLCONF)
    for url in urlconf.urls.urlpatterns:
        match = url.regex.match(request.META['PATH_INFO'][1:])
        if match:
            base_url = "/%s" % match.string[match.start():match.end()]
    return {"application_base_url": base_url}
Es ist zwar ein Schritt in die richtige Richtung, aber irgendwie gefällts mir nicht ... Verbesserungsvorschläge sind willkommen ...

Ach ja, zur Verwendung sollte in der "settings.py" so was stehen:

Code: Alles auswählen

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "mysite.testapp.context_processors.application_base_url",
)