[Fixed]-Django: Built-in include tag vs custom inclusion tag

18👍

They serve different purposes. The include tag simply includes the content from an existing template in its entirety and unmodified. A custom inclusion tag passes the context to a function which can contain logic to manipulate the context before passing it to a template.

For example, perhaps I have a panel that will be shown on multiple pages. The panel’s template requires a few specific queries to be passed to it through the context. The pages that contain the panel don’t require those context variables for anything else. If I include the panel template with the include tag, I would have to write those queries in every view that contains the panel and pass them as context variables.

Alternatively, I could write a custom inclusion tag that contains the queries and passes them to the panel’s template. By using the custom inclusion tag I wouldn’t need to repeat the code to produce its context in every view that contains the panel. My views would contain less code and would be less cluttered with context variables only used by the panel.

Although you are correct in the sense that a custom inclusion tag that simply passes on the context unmanipulated would be the same as the include tag.

👤dgel

9👍

Need to separate templates to smaller files? Use include tag (for readability and maintainability and DRY)

Need to include more code before rendering the template? Use inclusion tags (fetch more data, add some business logic.. it is really like another small url-less view. it is like a template function).

3👍

In principle, the point made by dgel’s and YardenST’s answers is correct. Additionally, a look into django’s code gives a good insight on how these two options are compared in performance.

When using the default template loaders, there is absolutely no difference between the two. Both eventually make a call to the InclusionTag render() function, which in turn makes a call to template Loader get_contents() that opens the template file from filesystem. render() only caches the file in case it is used in a template for loop.

As a side note, a difference in performance would be possible by using the django.template.loaders.cached.Loader.

Last, regarding dgel’s suggestion to use the inclusion tag for common context across different views: it is very much possible to avoid the small extra overhead of rendering an inclusion template, when the html markup is in a single base template that spans across many views, by using a ContextMixin. This is a quite common scenario for rendering eg. a main menu in a base template.

👤Wtower

1👍

Just recently faced this question as I was trying to find which route is best to take – include vs inclusion tag – when there’s no real extra logic that might go into an inclusion tag.

And I choose the inclusion tag for the following reasons:

  1. more compact and readable markup in templates
    <!-- include -->
    {% include "path/to/funky.html" with arg1=arg1 arg2=arg2 %}
    

    vs

    <!-- inclusion tag -->
    {% funky arg1 arg2 %}
    
  2. easier to maintain code, if you ever had to add custom logic to the tag then it’s easy to add
  3. it enforces you to use template variables that are scoped properly, so the inclusion tag cannot inherit a variable from the parent view, makes it more resilient against weird bugs
👤slajma

Leave a comment