Web Development with
Python & Django III

Templating

  • Assignment 6 is due April 27

Our Example Project

We're playing the role of a cheese enthusiast
who wants to build a site to:

  • Make our database of cheeses available to visitors
  • Allow visitors to rate cheeses they have tried

We created three views + templates:

  1. A view for the homepage
  2. A view listing cheeses we had data for
  3. A detail page with the name, country of origin and a description for individual cheeses

A closer look at templates


        
<html>
<head>
    <title>Cheeses We Have</title>
</head>
<body>
    <h1>Cheeses We Have</h1>
    <ul>
    {% for slug, name, country in cheeses %}
        <li>
            <a href="{% url 'cheese_detail' slug %}">{{ name }}</a>, from {{ country }}
        </li>
    {% endfor %}
    </ul>
</body>
</html>
        
    

Templates:

  • HTML files containing the static part of the page (what doesn't change from request to request)
  • Allow Python variables to be interpolated into the content when the template is rendered
  • Templates are rendered with a context, which is a dictionary of variable names mapped to values.

An example context:


        context = {
            "first_name": "Sally",
            "last_name": "Smith,
            "age": 35
        }
    

...and its accompanying template:


        
        {{ first_name }} {{ last_name }} is {{ age }} years old.
        
    

Control Flow: Conditionals


        {% if user.is_active %}
            Hello, active user.
        {% else %}
            Your user is no longer active.
        {% endif %}
    

        {% if user.age < 18 %}
            This user is not an adult.
        {% else %}
            This user is an adult.
        {% endif %}
    

        {% if user.is_active and user.age >= 18 %}
            This active user is an adult.
        {% endif %}
    

Control Flow: Loops


        <ul>
        {% for user in users %}
            <li>{{ user.name }}</li>
        {% empty %}
            <li>No users found.</li>
        {% endfor %}
        </ul>
    

        {% for key, value in some_dictionary.items() %}
            {{ key }} #{{ forloop.counter }} is {{ value }}
        {% endfor %}
    

Template Filters

  • Django template filters allow you to change how values are displayed
  • Filters look like this: {{ name|lower }}.
  • This displays the value of the {{ name }} variable after being filtered through the lower filter, which converts text to lowercase.
  • Use a pipe (|) to apply a filter.

Filter Examples

  • {{ value|default:"nothing" }} displays the value or a default if it's None.
  • {{ value|length }} displays the length of value.
  • {{ value|date:"Y-M-D" }} formats a date/datetime object
  • {{ value|first }} prints the first thing in a list {{ value|last }} does the opposite
  • {{ value|floatformat }} rounds a floating-point number.
  • There are many more!

Template Philosophy

  • Django’s template language is deliberately simple.
  • Keep logic and code separate from design.
  • Django’s templates are not Python code embedded into HTML; you can't do even a small fraction of what you can do in Python in a template
  • You can't paste Python code into a template
  • Templates are designed to be usable by non-programmers

Template Inheritance

  • Most HTML pages on a site will share at least some common parts
  • Remember D.R.Y — don't repeat yourself
  • Template inheritance allows you to build a base “skeleton” template that contains all the common elements of your site
  • You can then define blocks that child templates can override.

Here's an example base.html file

<html>
<head>
    <link rel="stylesheet" href="style.css">
    <title>{% block title %}Cheese Shop{% endblock %}</title>
</head>
<body>
    <h1 class="logo">The Cheese Shop</h1>
    <div id="navigation">
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/cheeses/">Cheeses</a></li>
        </ul>
    </div>
    <div id="content">
        {% block content %}{% endblock %}
    </div>
</body>
</html>

A child template for an individual
cheese detail page might look like this:

{% extends "base.html" %}

{% block title %}{{ cheese.name }}{% endblock %}


{% block content %}
<h2>{{ cheese.name }}</h2>
<p>Country of origin: {{ cheese.country }}</p>
<p>{{ cheese.description }}</p>
{% endblock %}

Bootstrap

  • Good design is difficult & CSS is hard
  • Bootstrap is a popular front-end open source toolkit
  • Provides nice looking defaults for typography, forms, navigation, etc.
  • Provides flexible and mobile-friendly page layouts
  • Easy way to make a site look nice without much work
  • We'll use this to make our site look a little better
Let's go back to where we left off last week...