Day 3 of 5
⏱ ~60 minutes
Django in 5 Days — Day 3

Templates

Build HTML pages with Django's template language. Inheritance with extends/blocks, reusable includes, and built-in filters.

Template Inheritance

Don't repeat your navbar and footer on every page. Define a base template once and extend it everywhere.

templates/base.html



  {% block title %}My Blog{% endblock %}


  

  
{% block content %} {% endblock %}
{% include 'partials/footer.html' %}
Finished this lesson?
templates/blog/post_list.html
{% extends 'base.html' %}

{% block title %}Blog Posts{% endblock %}

{% block content %}
  

All Posts

{% for post in posts %}

{{ post.title }}

{{ post.created_at|date:"M d, Y" }}

{{ post.body|truncatewords:30 }}

{% empty %}

No posts yet.

{% endfor %} {% endblock %}
Common Template Filters
{{ value|upper }}           → UPPERCASE
{{ value|lower }}           → lowercase
{{ date|date:"M d, Y" }}    → Jan 01, 2026
{{ body|truncatewords:30 }} → first 30 words...
{{ body|truncatechars:100 }} → first 100 chars...
{{ body|linebreaks }}        → 

tags from newlines {{ value|default:"N/A" }} → fallback if falsy

💡
The {% url 'view_name' %} tag generates URLs from named views. Never hardcode URLs in templates. If you change the URL pattern, the template still works because it looks up by name.
📝 Day 3 Exercise
Build the Blog Templates
  1. C
  2. r
  3. e
  4. a
  5. t
  6. e
  7. b
  8. a
  9. s
  10. e
  11. .
  12. h
  13. t
  14. m
  15. l
  16. w
  17. i
  18. t
  19. h
  20. n
  21. a
  22. v
  23. a
  24. n
  25. d
  26. f
  27. o
  28. o
  29. t
  30. e
  31. r
  32. b
  33. l
  34. o
  35. c
  36. k
  37. s
  38. .
  39. C
  40. r
  41. e
  42. a
  43. t
  44. e
  45. p
  46. o
  47. s
  48. t
  49. _
  50. l
  51. i
  52. s
  53. t
  54. .
  55. h
  56. t
  57. m
  58. l
  59. a
  60. n
  61. d
  62. p
  63. o
  64. s
  65. t
  66. _
  67. d
  68. e
  69. t
  70. a
  71. i
  72. l
  73. .
  74. h
  75. t
  76. m
  77. l
  78. t
  79. h
  80. a
  81. t
  82. e
  83. x
  84. t
  85. e
  86. n
  87. d
  88. i
  89. t
  90. .
  91. A
  92. d
  93. d
  94. p
  95. a
  96. g
  97. i
  98. n
  99. a
  100. t
  101. i
  102. o
  103. n
  104. t
  105. o
  106. t
  107. h
  108. e
  109. l
  110. i
  111. s
  112. t
  113. v
  114. i
  115. e
  116. w
  117. u
  118. s
  119. i
  120. n
  121. g
  122. D
  123. j
  124. a
  125. n
  126. g
  127. o
  128. '
  129. s
  130. P
  131. a
  132. g
  133. i
  134. n
  135. a
  136. t
  137. o
  138. r
  139. .

Day 3 Summary

  • {% extends 'base.html' %} + {% block content %}{% endblock %} = DRY templates.
  • {% url 'name' %} generates URLs. Never hardcode. {% include 'partial.html' %} inserts snippets.
  • Filters transform values: |date, |truncatewords, |upper, |default.
  • {% for item in list %}{% empty %}{% endfor %} — the empty block handles empty lists gracefully.