Django | How To – Templates konfigurieren

uploads/2021/10/django_howto_templates_000c.png

Allgemein / Vorbereitung

Um in einem Django-Projekt mit mehreren Anwendungen die HTML-Templates zu konfigurieren sind mehrere Schritte notwendig.

Ausgangsbasis ist die nachfolgende Verzeichnisstruktur (ein Projekt mit 2 Anwendungen).

Basisprojekt einrichten

<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">➜ pipenv --python 3.10
➜ pipenv shell
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">➜ pip install django
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">➜ djangop-admin startproject project
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">➜ cd project
➜ mkdir apps
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">➜ mkdir apps\core
➜ django-admin startapp core apps\core
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">➜ mkdir apps\frontend
➜ django-admin startapp frontend apps\frontend

Dies ergibt die folgende Verzeichnisstruktur:

Der zweite Ordner project ist das Django-Projekt, in dem sich alle für das Projekt notwendigen Dateien befinden.

Wird in den nachfolgenden Beschreibungen vom dem Ordner project gesprochen, so ist immer der zweite gemeint (project/project)

<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">➜ python manage.py migrate
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">➜ python manage.py createsuperuser --email admin@localhost --username admin
Password:
Password (again):
Superuser created successfully.

Anwendungen hinzufügen

Im nächsten Schritt werden die beiden erstellten Anwendungen (Core und Frontend) dem Django-Projekt hinzugefügt. Da sie in einem Unterverzeichnis (apps) liegen, muss ihre Konfiguration angepasst werden.

In dere Datei apps.py der jeweiligen Anwendung (apps/core/apps.py und apps/frontend/apps.py) wirr der Name angepasst:

<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">django.core.exceptions.ImproperlyConfigured: Cannot import 'frontend'. Check that 'apps.frontend.apps.FrontendConfig.name' is correct.

Im Anschluss daran werden die beiden Anwendungen dem Projekt hinzugefügt. Dies erfolgt in der Datei project/settings.py:

<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="9,10" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'apps.core',
    'apps.frontend'
]

Einfache Views erstellen

Ein Template ist die Basis eines Views.

Daher richten wir für jede Anwendung einen einfachen View ein: in apps/core/views.py und apps/frontend/views.py:

<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">from django.shortcuts import render
from django.views import generic

class IndexView(generic.TemplateView):
    """
    IndexView:
    """
    module = 'indexView'
    template_name = 'core/index.html'

Im letzten Vorbereitungsschritt konfigurieren wir die URLs für unsere Anwendungen bzw die beiden eingerichteten Views:

<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">from django.contrib import admin
from django.urls import path

import apps.core.views as core
import apps.frontend.views as frontend

urlpatterns = [
    path('admin/', admin.site.urls),
    path('frontend/', frontend.IndexView.as_view(), name='index'),
    path('core', core.IndexView.as_view(), name='index'),

]

Als Ergebnis sollten wir bei beiden URLs einen Fehler sehen.

Dies was zu erwarten, da wir die notwendigen Templates ja erst jetzt einrichten werden:

Erstellen eines Templates für die Anwendung core: apps/core/templates/core/index.html

http://localhost:8000/core

http://localhost:8000/frontend

Als erstes wir uns mitgeteilt, das ein gewünschtes Template in der nachfolgenden Reihenfolge gesucht wird. Es werden als (wir oben bereits erwähnt) mehrere Verzeichnisse durchsucht, um ein passendes Template zu finden.

<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">Template-loader postmortem
Django tried loading these templates, in this order:

Using engine django:

Als erstes werden Verzeichnisse der Django-Installation durchsucht. Hierunter liegen z. B. die Templates für die Administration oder die Anmeldung.

<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">django.template.loaders.app_directories.Loader: 
...\lib\site-packages\django\contrib\admin\templates\frontend\index.html (Source does not exist)

django.template.loaders.app_directories.Loader: 
...\lib\site-packages\django\contrib\auth\templates\frontend\index.html (Source does not exist)

Im Anschluss werden dann die Verzeichnisse unserer Anwendungen durchsucht.

<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">django.template.loaders.app_directories.Loader: ...\project\apps\core\templates\frontend\index.html (Source does not exist)

django.template.loaders.app_directories.Loader: ...\project\apps\frontend\templates\frontend\index.html (Source does not exist)

Um nun ein gewünschtes Template zu finden, werden zwei Informationen benötigt:

  • der Name des Template
  • das Verzeichnis

Name des Templates

Der Name des Templates wird im View angegeben: apps/core/views.py:

<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">class IndexView(generic.TemplateView):
    module = 'indexView'
    template_name = 'core/index.html'

Verzeichnis

Das Verzeichnis selbst wird über die Suchreihenfolge der zu verwendenden Template-Verzeichnisse ermittelt. Das erste Verzeichnis, dass das gewünschte Template beinhaltet, wird verwendet.

Ermitteln des Verzeichnisses

Im Falle unserer Anwendung frontend werden die nachfolgenden Verzeichnisse durchsucht, ob sie das Template core/index.html beinhalten:

Erstellen eines Templates für die Anwendung frontend: apps/frontend/templates/frontend/index.html

Richten sie einen Neuen View in der Anwendung frontend ein: apps/frontend/views.py

<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">class BaseView(generic.TemplateView):
    module = 'baseView'
    template_name = 'base.html' 

Erstellen Sie eine URL für diesen View in project/urls.py

<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">urlpatterns = [
    path('admin/',      admin.site.urls),
    path('core',        core.IndexView.as_view(),      name='index'),
    path('frontend/',   frontend.IndexView.as_view(),  name='index'),
    path('base/',       frontend.BaseView.as_view(),   name='base'),
]

Öffnen Sie den Browser um diese URL anzuzeigen;

http://localhost:8000/base

Wie zu erwarten war, wird das Template nicht gefunden:

Gemeinsame Templates für alle Anwendungen

Um Templates einzurichten, die von mehreren Anwendungen verwendet werden, empfiehlt es sich, ein Verzeichnis templates auf der gleichen Ebene, wie die Anwendungen, einzurichten

<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        ....

Öffnen Sie den Browser um diese URL anzuzeigen;

http://localhost:8000/base

Das zusätzliche Verzeichnis wird nun auch durchsucht:

<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">Template-loader postmortem
Django tried loading these templates, in this order:

Using engine django:
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="1" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">django.template.loaders.filesystem.Loader: ...\project\templates\base.html (Source does not exist)
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">django.template.loaders.app_directories.Loader: ...\.venv\lib\site-packages\django\contrib\admin\templates\base.html (Source does not exist)
django.template.loaders.app_directories.Loader: ...\.venv\lib\site-packages\django\contrib\auth\templates\base.html (Source does not exist)
django.template.loaders.app_directories.Loader: ...\project\apps\core\templates\base.html (Source does not exist)
django.template.loaders.app_directories.Loader: ...\project\apps\frontend\templates\base.html (Source does not exist)

Erstellen Sie nun in diesem Verzeichnis (templates) das Template base.html

http://localhost:8000/base

The Latest