Templates¶
Theory¶
The final product of our work, visible to the user, is the website. Thanks to Django, we can generate dynamic pages. Template languages are used for convenient page generation. For isolation of template HTML code, templates are placed in separate files. Templates are filled with values processed by the view and placed in the so-called context template.
Practice¶
Let's put the following template code in the file viewer/templates/hello.html:
<!DOCTYPE html>
<html>
<body>
<h1>Welcome to HollyMovies!</h1>
{% for adjective in adjectives %}
{% if adjective != 'cruel' %}
<p>This is a {{ adjective }} world...</p>
{% endif %}
{% endfor %}
</body>
</html>
To render it use the render
function in the view and indicate with what data we want to fill it:
from django.shortcuts import render
def hello(request, s0):
s1 = request.GET.get('s1', '')
return render(
request, template_name='hello.html',
context={'adjectives': [s0, s1, 'beautiful', 'wonderful']}
)
Extension¶
Templates can inherit from each other. In this way, we can share identical code used in multiple places. We do this using the extends tag. First, however, we need to define the base.html base template, in which we will embed the base of the HTML document structure, Bootstrap styles and scripts, and a navigation bar and main content container that is consistent for all pages:
{% load static %}
<html {% if LANGUAGE_CODE %}lang="{{ LANGUAGE_CODE }}"{% endif %}>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>HollyMovies</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container fixed">
<a class="navbar-brand" href="/">HollyMovies</a>
<button
class="navbar-toggler" type="button"
data-toggle="collapse" data-target="#navbarNavAltMarkup"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<a class="nav-item nav-link active" href="/">
Home
</a>
</div>
</div>
</div>
</nav>
<div class="container">
<div class="jumbotron">
{% block content %}{% endblock %}
</div>
</div>
</body>
</html>
The base template is extended by the template hello.html:
{% extends "base.html" %}
{% block content %}
<h1>Welcome to HollyMovies!</h1>
{% for adjective in adjectives %}
{% if adjective != 'cruel' %}
<p>This is a {{ adjective }} world...</p>
{% endif %}
{% endfor %}
{% endblock %}
This is how we embed the code of the hello.html template, specifically its content
block, inside the content
** block in the base.html
template.
List of movies¶
In the new base template, let's base the list of movies added to the base:
{% extends "base.html" %}
{% block content %}
<h1>Welcome to HollyMovies!</h1>
<ul>
{% for movie in movies %}
<li>
{{ movie.title }} ({{ movie.released.year }}) - {{ movie.genre.name }}
</li>
{% endfor %}
</ul>
{% endblock %}
Add to the context the variable movies
, which is the collection of movies from the database.
from django.shortcuts import render
from viewer.models import Movie
def movies(request):
return render(
request, template_name='movies.html',
context={'movies': Movie.objects.all()}
)
Let's not forget to rename the view function in urls.py!
from django.contrib import admin
from django.urls import path
from viewer import views
from viewer.models import Genre, Movie
admin.site.register(Genre)
admin.site.register(Movie)
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.movies)
]
Internal links¶
Applications in Django should not use names that may change due to business requirements that are irrelevant to the logic. Therefore, we should never link to pages from our application directly, but by using key-names that are not visible in the user interface, given with the parameter name
of the path
function in the urls.py file.
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.movies, name='index')
]
<a class="navbar-brand" href="{% url 'index' %}">HollyMovies</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<a class="nav-item nav-link active" href="{% url 'index' %}">
Home
</a>
</div>
</div>