In this lesson, youâll learn about template inheritance as well as a common software development principle: DRY (Donât Repeat Yourself). Djangoâs template inheritance allows you to write a particular bit of code only once in one place and then inherit from there to the other places where you want to use it.
Template Inheritance
00:00
Welcome to this video about template inheritance. Here, I want to sneak in a little information about a common software development principle. Itâs called DRY: donât repeat yourself. Letâs take a look at how this applies in our templates. So, back here in all_projects.html, where we just fixed up our button, thereâs all this HTML structure up here: a <!DOCTYPE> declaration with HTML tags, we have the <head>, and remember, we had to copy this link to the Bootstrap CDN from our index.html page that weâre not using anymore.
00:37 So thereâs some leftover code, but maybe we kept it around because we thought this could be useful. Itâs all, like, lots of excuses for things that you actually donât want to do.
00:47
So Iâll go ahead and clean this up a bit. The first thing I want to do is get rid of index.html. We donât need this, weâre not linking here anymore, so letâs just delete it for now.
01:01
Okay. Next, we want to not have to repeat ourselves, so, âDo not repeat yourself.â We want to seeâlike, inside of detail, I have this <!DOCTYPE> declaration and everything again.
01:13 I would have to drop in the Bootstrap CDN again. This is all stuff that we donât want to do twice, because itâs exactly the same, okay? Django has something thatâs called template inheritance that allows us to only do this once and in one place, and then inherit from there to the other places where weâre using it.
01:33 To build this in the correct way, letâs first take a look at a couple of slides and walk over it, and then weâll come back to the code to actually build it out.
01:42
To avoid repeating ourselves, weâre going to look at two files. First one is going to be base.html. Inside of base.html is where weâre going to put all the basic HTML code and something like a <footer>, or a <header>âsomething thatâs going to repeat all over in every page for my whole website.
02:01
So, inside of base.htmlâand imagine that on top here, is going to be the <!DOCTYPE> declaration, weâre going to have our <head>, itâs going to be the same everywhereâthe <title>, et cetera, and then, yeah, letâs assume down here is a <footer>, for example.
02:14
Somewhere in there, Iâm putting this {% block content %}. Itâs a template tag thatâs just called a block tag, I guess. It consists of two parts: the one that opens it and the one that closes it.
02:27 I want you to imagine it just like that, that thereâs this space that weâre opening up by creating this block, and this space is ready to take some changing HTML content.
02:38
But weâre not going to be putting this inside of base.html, this is just where itâs eventually going to go. So, everything around it stays the same, and this one is going to get exchanged with whatever weâre going to put inside of {% block content %} in our second file. So, letâs take a look at the second file.
02:55
This one can be whatever template youâre going to be mixing together with base.html, so this can be multiple ones. For us in our project, itâs going to be all_projects as well as detail.
03:08
Both of them are going to inherit from base.html.
03:12
Inside of thisâwhatever template it isâthere are two things to consider. So the first thing, we needâagainâthe same block with the same name that we gave it over in base.html because we need to open up this space again.
03:25
Now, weâre going to be putting something in there, actually. But we need to connect to base.html by saying, âOkay, this is this block, whatever is in base.html under this block is going to be replaced with what weâre putting in here.â So, thatâs part one, and the second one is at the very top we need to extend base.html.
03:44
Another Django template tag, and what it simply does is it creates this connection between these two templates. And then finally, if we have all this together, in here between {% block content %} and {% endblock %} is where weâre going to write our changing HTML thatâs going to be specific for the page that weâre currently looking at.
04:06 Okay, so that was very theoretical. Letâs build this out in practice over in our code.
04:14
The first thing Iâm going to do is Iâm going to create base.html.
04:23
PyCharm already gives us the structure, so Iâm not going to have to type it out. One thing I will do though, is Iâm going to call my page Portfolio, give it a title, because this is going to be for every page the same, and thatâs what I want.
04:40
And then in here, in body, is where Iâm going to open up the block. Iâm going to call this block content. Itâs the standard way of calling these blocks in Django.
04:51 You can have multiple different blocks, and then you just need to give them different names but often, this is fine. Often, one of them is enough. Great! So now here, I opened up the space that allows me to later input HTML code that Iâm going to write in other templates.
05:10
So if I head back over to all_projects, now, a lot of these things become obsolete. I can get rid of this, I donât need it. The <body> tag, I already have this.
05:23
So, this is going to be interesting. We want to have this in all pagesâour Bootstrap linkâso Iâm taking it out of here, putting it into the head in our base.html so that we have access to it here, as well as in whichever other template weâre extending this from.
05:44
Back thereâoh, so itâs telling me I donât need those anymore, so letâs get rid of themâthereâs only two things missing here now. One is, I need to define the block. Iâm going to say {% block content %}.
05:58
Then remember, in between, we put our HTML of that specific template, and then Iâm going to end the block down here. So, that was step one: creating the {% block content %} and putting our HTML in there. And then step two, you need this other template tag that tells us that weâre extending from base.html.
06:26 There it is! Now, weâre saving up on all this boilerplate HTML beginning, we donât need to repeat that Bootstrap CDN, et cetera. And the only HTML that we have in this template is that HTML thatâs actually specific for this template. Letâs double-check whether this is still working.
06:46 Reload my page. Everythingâs still fine. Awesome. Letâs do the second template!
06:57
Back here in detail, we have a lot of stuff that repeats again that we can get rid of.
07:20 Thatâs number one, and number twoâextending.
07:37
And with this, we follow the Donât Repeat Yourself principle and we keep our templates much easier to read, because the only thing that matters here is the code thatâs specific to this template and we only keep that code in here and we keep everything else, everything that repeats, inside of base.html.
07:57
Just double-checking whether everything still works. Perfect! You can also see that Bootstrap style gets applied to this already because now weâre extending the base.html template that has the Bootstrap CDN included.
08:13 So, itâs going to make it easy for us to nicely style this page, as well, which is exactly what weâre going to do in the next video. See you there!
Martin Breuss RP Team on Oct. 23, 2019
Are you still doing {% load static %} also in the child templates? I assume you are probably running into this situation.
charneuk on Aug. 13, 2020
I am also getting this error:
TemplateSyntaxError at /projects/1
Invalid block tag on line 12: 'enblock', expected 'endblock'. Did you forget to register or load this tag?
Martin Breuss RP Team on Aug. 14, 2020
Hi @charneuk. Looks like in your case it’s a typo. Double-check your spelling and look at the quoted words in your error message.
Django’s quite a stickler with spelling, but at least it is straightforward about it. :)
charneuk on Aug. 14, 2020
well that worked, ty. HA. damn spelling typos.
gordoncampbell on Dec. 8, 2021
Hi @martin, great videos. Simply explained.
As a fan of working efficiently, I’d love to know what plugin you are using for code completion for the Django Templating Syntax (e.g. when you started typing:
{$ block ...
and the IDE completed it with:
{% endblock %}
Many thanks
Martin Breuss RP Team on Dec. 9, 2021
Hi @gordoncampbell I think I was using the Djaneiro plugin for PyCharm for this course.
You’ll be able to find some plugin for that also if you’re using a different editor. It’s a collection of shortcodes that create common language patterns. Hope that helps! :)
Katya on June 18, 2023
hello! for some reason im getting a blank page after clicking the “read more” in the project page. it worked properly and displayed all the elements before i made the changes shown in the video but it dosent work after. I made sure that the code in html files is correct by compering it to yours. what can be the reason for that?
thank you for your help and guidance! katya
Martin Breuss RP Team on June 20, 2023
@Katya it’s hard to say without seeing your code. If it was working before and stopped working after this change, then there’s probably some small error in how you set up template inheritance.
Does the project page itself still work? If yes, then you could double-check how you set up template inheritance there and find out whether there’s a typo somewhere in the detail.html page.
If you have your project code up on GitHub somewhere you can share a link and I can take a look.
Aaron Ruhl on Jan. 12, 2025
Watch your curly braces…I had a ) instead of } at the end of the line 3: {% block content %). I just spent way too much time discovering that. Otherwise this tutorial still works so far with latest Django 5.1.4.
Become a Member to join the conversation.

Gascowin on Oct. 21, 2019
I accidentally (or shall i say intentionally) included
in base.html since it gets used in the other templates as well but ended up with another one of our “friends”; “TemplateSyntaxError”. The error asks “did you forget to register or load this tag?”
Am I missing something here?…or does this approach not work for ‘static’ files? Thanks.