Django normally escapes HTML in template data, turning tags such as <b> into visible text. mark_safe() deliberately marks a string as trusted HTML, returning a SafeString that Django will not escape. section 3.7
Use it when the string already contains HTML you intentionally want rendered. Treat it like a “this is safe” sticker, not a security force field: do not apply it casually to untrusted user input. section 3.7
Render an intentional line break
from django.utils.safestring import mark_safe instrument = mark_safe("drum<br/>") data = {"instrument": instrument} # A template value such as {{ instrument }} renders drum<br/> # as an actual line break rather than escaped text. section 3.7
Keep these behavior rules in mind:
- mark_safe(string) takes the string to trust and returns a SafeString. section 3.7
- Operations on a SafeString produce an ordinary str, so modifying it requires marking the result safe again. section 3.7
- For dynamically composed HTML, prefer format_html(), which fills placeholders and returns a SafeString. section 3.7
- When assembling multiple HTML links in a Django admin column, mark the completed string safe after appending the links. section 5.5
Listing 3.13 Using mark_safe() to mark data as safe in the Django REPL
>>> from django.utils.safestring import mark_safe
>>> instrument = mark_safe("drum<br/>")
>>> data = {"instrument":instrument}
>>> t.render(Context(data))
"I love the sound a drum<br/> makes.\n
A shiny drum<br/> is good.\n\\n\\n
Don't put a drum<br/> too close to your ear.\n\\n"
Compare ordinary template escaping with a marked-safe value containing a br tag. section 3.7
