overriding-templates.txt 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. =========================
  2. How to override templates
  3. =========================
  4. In your project, you might want to override a template in another Django
  5. application, whether it be a third-party application or a contrib application
  6. such as ``django.contrib.admin``. You can either put template overrides in your
  7. project's templates directory or in an application's templates directory.
  8. If you have app and project templates directories that both contain overrides,
  9. the default Django template loader will try to load the template from the
  10. project-level directory first. In other words, :setting:`DIRS <TEMPLATES-DIRS>`
  11. is searched before :setting:`APP_DIRS <TEMPLATES-APP_DIRS>`.
  12. .. seealso::
  13. Read :ref:`overriding-built-in-widget-templates` if you're looking to
  14. do that.
  15. Overriding from the project's templates directory
  16. =================================================
  17. First, we'll explore overriding templates by creating replacement templates in
  18. your project's templates directory.
  19. Let's say you're trying to override the templates for a third-party application
  20. called ``blog``, which provides the templates ``blog/post.html`` and
  21. ``blog/list.html``. The relevant settings for your project would look like::
  22. from pathlib import Path
  23. BASE_DIR = Path(__file__).resolve().parent.parent
  24. INSTALLED_APPS = [
  25. ...,
  26. "blog",
  27. ...,
  28. ]
  29. TEMPLATES = [
  30. {
  31. "BACKEND": "django.template.backends.django.DjangoTemplates",
  32. "DIRS": [BASE_DIR / "templates"],
  33. "APP_DIRS": True,
  34. # ...
  35. },
  36. ]
  37. The :setting:`TEMPLATES` setting and ``BASE_DIR`` will already exist if you
  38. created your project using the default project template. The setting that needs
  39. to be modified is :setting:`DIRS<TEMPLATES-DIRS>`.
  40. These settings assume you have a ``templates`` directory in the root of your
  41. project. To override the templates for the ``blog`` app, create a folder
  42. in the ``templates`` directory, and add the template files to that folder:
  43. .. code-block:: none
  44. templates/
  45. blog/
  46. list.html
  47. post.html
  48. The template loader first looks for templates in the ``DIRS`` directory. When
  49. the views in the ``blog`` app ask for the ``blog/post.html`` and
  50. ``blog/list.html`` templates, the loader will return the files you just created.
  51. Overriding from an app's template directory
  52. ===========================================
  53. Since you're overriding templates located outside of one of your project's
  54. apps, it's more common to use the first method and put template overrides in a
  55. project's templates folder. If you prefer, however, it's also possible to put
  56. the overrides in an app's template directory.
  57. First, make sure your template settings are checking inside app directories::
  58. TEMPLATES = [
  59. {
  60. # ...
  61. "APP_DIRS": True,
  62. # ...
  63. },
  64. ]
  65. If you want to put the template overrides in an app called ``myapp`` and the
  66. templates to override are named ``blog/list.html`` and ``blog/post.html``,
  67. then your directory structure will look like:
  68. .. code-block:: none
  69. myapp/
  70. templates/
  71. blog/
  72. list.html
  73. post.html
  74. With :setting:`APP_DIRS<TEMPLATES-APP_DIRS>` set to ``True``, the template
  75. loader will look in the app's templates directory and find the templates.
  76. .. _extending_an_overridden_template:
  77. Extending an overridden template
  78. ================================
  79. With your template loaders configured, you can extend a template using the
  80. :ttag:`{% extends %}<extends>` template tag whilst at the same time overriding
  81. it. This can allow you to make small customizations without needing to
  82. reimplement the entire template.
  83. For example, you can use this technique to add a custom logo to the
  84. ``admin/base_site.html`` template:
  85. .. code-block:: html+django
  86. :caption: ``templates/admin/base_site.html``
  87. {% extends "admin/base_site.html" %}
  88. {% block branding %}
  89. <img src="link/to/logo.png" alt="logo">
  90. {{ block.super }}
  91. {% endblock %}
  92. Key points to note:
  93. * The example creates a file at ``templates/admin/base_site.html`` that uses
  94. the configured project-level ``templates`` directory to override
  95. ``admin/base_site.html``.
  96. * The new template extends ``admin/base_site.html``, which is the same template
  97. as is being overridden.
  98. * The template replaces just the ``branding`` block, adding a custom logo, and
  99. using ``block.super`` to retain the prior content.
  100. * The rest of the template is inherited unchanged from
  101. ``admin/base_site.html``.
  102. This technique works because the template loader does not consider the already
  103. loaded override template (at ``templates/admin/base_site.html``) when
  104. resolving the ``extends`` tag. Combined with ``block.super`` it is a powerful
  105. technique to make small customizations.