Typorithm · easy

Templates, escaping and missing values

pythondjangoindependent-practice
Saved on this device
Full lesson · 4 learning steps Open any exercise for focused practice
1

Step 1 of 4 · intro card

Templates, escaping and missing values

0%

Concept and contract

Keep untrusted text as text in an HTML template and distinguish a missing value from an intentionally empty one.

A template combines a presentation structure with context values, and HTML output needs a clear escaping boundary. A title containing angle brackets should remain visible text rather than becoming a new HTML element.

This lesson uses Django’s template engine directly so the transformation is observable without a browser. It does not evaluate the supplied title as template source, and it does not use real user data or a remote template loader.

Mechanism and worked example

The worked template places title into an automatically escaped variable position.

The worked template places title into an automatically escaped variable position. Django escapes reserved HTML characters while ordinary text remains readable.

The context value is data; constructing a new template string by concatenating that value would cross a different and unsafe boundary. The example imports mark_safe only to make the counterexample’s bypass explicit, not as a recommendation for handling an untrusted title.

Complete worked example

python

from bootstrap_lab import django_setup
django_setup(__name__)

from django.template import Context, Template
from django.utils.safestring import mark_safe

def rendered_title(title):
    template = Template("{{ title }}")
    return template.render(Context({"title": title}))
Reasoning
The worked template places title into an automatically escaped variable position. Django escapes reserved HTML characters while ordinary text remains readable.

Counterexamples and common mistakes

The counterexample marks the title safe before rendering.

The counterexample marks the title safe before rendering. That suppresses escaping and turns a supplied element spelling into HTML markup.

Escaping is context-dependent: HTML text escaping does not automatically make a value suitable for JavaScript, a URL or an authorization decision. Do not disable escaping merely because an output contains unexpected punctuation. First identify the output context and the intended representation contract.

Counterexample: a runnable framework mistake

python

from bootstrap_lab import django_setup
django_setup(__name__)

from django.template import Context, Template
from django.utils.safestring import mark_safe

def rendered_title(title):
    template = Template("{{ title }}")
    return template.render(Context({"title": mark_safe(title)}))
Reasoning
The counterexample marks the title safe before rendering. That suppresses escaping and turns a supplied element spelling into HTML markup.

Independent practice: one bounded framework change

Use default_if_none to display Untitled only for a None value, while preserving an intentionally empty string.

Use default_if_none to display Untitled only for a None value, while preserving an intentionally empty string. Keep HTML escaping enabled for ordinary supplied text.

Begin with None, then an empty value and finally a string containing an HTML element spelling. The small filter change teaches a missing-value distinction without asking you to build a layout system or implement a custom escaping function.

Step 1: Provide Untitled for None while preserving an empty string. Step 2: Keep supplied HTML element spellings escaped.

Practice starter: solve before reading the solution

python

from bootstrap_lab import django_setup
django_setup(__name__)

from django.template import Context, Template
from django.utils.safestring import mark_safe

def rendered_title(title):
    # Remove this placeholder, then adapt the retained baseline:
    # Provide Untitled for None while preserving an empty string.
    raise NotImplementedError
    template = Template("{{ title }}")
    return template.render(Context({"title": title}))
Reasoning
Provide Untitled for None while preserving an empty string. Keep supplied HTML element spellings escaped.
  • Hint 1: Use default_if_none rather than a general truthiness default.
  • Hint 2: Treat title as context data, never as new template source.

Solution, tests and trade-offs

The expected results include ordinary text, an escaped element and an ampersand, so a bypass cannot pass by returning a superficially similar string.

The expected results include ordinary text, an escaped element and an ampersand, so a bypass cannot pass by returning a superficially similar string. Practice adds the difference between None and empty text.

The checks invoke the real pinned template engine and compare actual output. They do not claim browser-level content-security-policy coverage, and a default filter should not be treated as validation of a missing required domain field.

Practice solution and acceptance checks

python

from bootstrap_lab import django_setup
django_setup(__name__)

from django.template import Context, Template
from django.utils.safestring import mark_safe

def rendered_title(title):
    template = Template('{{ title|default_if_none:"Untitled" }}')
    return template.render(Context({"title": title}))
Reasoning
The expected results include ordinary text, an escaped element and an ampersand, so a bypass cannot pass by returning a superficially similar string. Practice adds the difference between None and empty text.

Interview reasoning and next step

Explain the difference between trusted template source and untrusted context data.

Explain the difference between trusted template source and untrusted context data. Then describe why default and default_if_none can produce different results for false-like values.

A larger Django application can reuse base templates, components and named URLs while preserving the same context boundary. The following lesson moves validation earlier, ensuring a submitted form meets its contract before any saved model or presentation depends on the values.

Optional stretch — after the core task works: Render a JSON value with the framework’s appropriate script-safe helper and explain the context difference.

Computer practice: https://applydjinn.com/typorithm/python-frameworks-lab-20261105.zip. Install the pinned dependencies in an isolated environment, run verify.py --track django, then edit the retained exercise baseline and check it with --practice dj-templates. The lab uses owned in-memory databases, local framework clients and tiny CPU tensors. It never reads the working ApplyDjinn database, contacts production feeds or downloads models.

Keep untrusted text as text in an HTML template and distinguish a missing value from an intentionally empty one.