{"id":1717,"date":"2026-09-22T06:46:51","date_gmt":"2026-09-22T06:46:51","guid":{"rendered":"https:\/\/nayananimsara.online\/?p=1717"},"modified":"2026-09-22T07:13:06","modified_gmt":"2026-09-22T07:13:06","slug":"create-a-django-home-page","status":"publish","type":"post","link":"https:\/\/nayananimsara.online\/create-a-django-home-page\/","title":{"rendered":"Create a Django Home Page That Actually Looks Like a Website"},"content":{"rendered":"\n<h1 id=\"create-a-django-home-page-that-actually-looks-like-a-website\" class=\"wp-block-heading\">Create a Django Home Page That Actually Looks Like a Website<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">create a Django home page with navigation and base template By this point in the series, your Django project can respond to a browser request, but if you&#8217;ve been following along, your homepage is still just one line of plain text sitting on a blank page. That&#8217;s fine for testing a view, but a real homepage needs at least some structure \u2014 a heading, some navigation, maybe a bit of color \u2014 before it looks like an actual site instead of a debug message.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We haven&#8217;t covered Django&#8217;s template system yet in this course, so we&#8217;re not reaching for that here. Everything in this post still goes through <code>HttpResponse<\/code>, the same way every view has so far. This is genuinely how a lot of people build their first real page, before templates get introduced as a better way to manage larger amounts of HTML.<\/p>\n\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Table of Contents<\/h2><nav><ul><li><a href=\"#create-a-django-home-page-that-actually-looks-like-a-website\">Create a Django Home Page That Actually Looks Like a Website<\/a><ul><li><a href=\"#why-http-response-still-works-fine-here\">Why HttpResponse Still Works Fine Here<\/a><\/li><li><a href=\"#step-1-write-the-html-as-a-python-string\">Step 1: Write the HTML as a Python String<\/a><\/li><li><a href=\"#step-2-add-some-styling-without-static-files\">Step 2: Add Some Styling Without Static Files<\/a><\/li><li><a href=\"#step-3-making-the-navigation-links-actually-work\">Step 3: Making the Navigation Links Actually Work<\/a><\/li><li><a href=\"#where-this-approach-starts-to-break-down\">Where This Approach Starts to Break Down<\/a><\/li><li><a href=\"#a-small-practical-tip\">A Small Practical Tip<\/a><\/li><li><a href=\"#where-this-connects-in-the-series\">Where This Connects in the Series<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Creating Views And URL For That The Secound Image You Can See How We create URL IN APP level Finanly In Third Image You Can See How we Configure URL Patten in Project Level <\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"491\" src=\"https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-10-1024x491.png\" alt=\"create a Django home page with navigation and base template\" class=\"wp-image-1718\" srcset=\"https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-10-1024x491.png 1024w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-10-767x368.png 767w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-10-300x144.png 300w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-10-1536x737.png 1536w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-10.png 1906w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>App Level urls.py File<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"454\" src=\"https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-12-1024x454.png\" alt=\"create a Django home page with navigation and base template\" class=\"wp-image-1721\" srcset=\"https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-12-1024x454.png 1024w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-12-768x340.png 768w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-12-300x133.png 300w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-12.png 1070w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Project Level urls,py File<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"895\" height=\"346\" src=\"https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-13.png\" alt=\"create a Django home page with navigation and base template\" class=\"wp-image-1722\" srcset=\"https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-13.png 895w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-13-766x296.png 766w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-13-300x116.png 300w\" sizes=\"(max-width: 895px) 100vw, 895px\" \/><\/figure>\n\n\n\n<h2 id=\"why-http-response-still-works-fine-here\" class=\"wp-block-heading\">Why HttpResponse Still Works Fine Here<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><code>HttpResponse<\/code> accepts a string, and that string can be full HTML, not just plain text. Nothing stops you from writing an entire page&#8217;s markup inside it. It gets messy once a page grows large, which is exactly the problem templates solve later on \u2014 but for a single homepage with a handful of sections, it&#8217;s a perfectly reasonable way to build something real right now.<\/p>\n\n\n\n<h2 id=\"step-1-write-the-html-as-a-python-string\" class=\"wp-block-heading\">Step 1: Write the HTML as a Python String<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Open <code>views.py<\/code> and update your <code>home<\/code> view. Instead of a single sentence, build the full HTML structure inside a triple-quoted string:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from django.http import HttpResponse\n\ndef home(request):\n    html = \"\"\"\n    &lt;!DOCTYPE html&gt;\n    &lt;html lang=\"en\"&gt;\n    &lt;head&gt;\n        &lt;meta charset=\"UTF-8\"&gt;\n        &lt;title&gt;My Django Site&lt;\/title&gt;\n    &lt;\/head&gt;\n    &lt;body&gt;\n        &lt;nav&gt;\n            &lt;a href=\"\/\"&gt;Home&lt;\/a&gt;\n            &lt;a href=\"\/about\/\"&gt;About&lt;\/a&gt;\n        &lt;\/nav&gt;\n\n        &lt;main&gt;\n            &lt;h1&gt;Welcome to my site&lt;\/h1&gt;\n            &lt;p&gt;This homepage is built directly inside the view, using HttpResponse.&lt;\/p&gt;\n        &lt;\/main&gt;\n\n        &lt;footer&gt;\n            &lt;p&gt;&amp;copy; 2026 My Django Site&lt;\/p&gt;\n        &lt;\/footer&gt;\n    &lt;\/body&gt;\n    &lt;\/html&gt;\n    \"\"\"\n    return HttpResponse(html)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Refresh your browser and you&#8217;ll see a proper page now \u2014 a navigation bar, a heading, a footer \u2014 all without touching a single template file. The triple quotes let the string span multiple lines, which makes writing full HTML like this manageable.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"491\" src=\"https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-11-1024x491.png\" alt=\"create a Django home page with navigation and base template\" class=\"wp-image-1720\" srcset=\"https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-11-1024x491.png 1024w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-11-1536x737.png 1536w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-11-300x144.png 300w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-11-767x368.png 767w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-11.png 1906w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"742\" src=\"https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-15-1024x742.png\" alt=\"create a Django home page\" class=\"wp-image-1725\" srcset=\"https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-15-1024x742.png 1024w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-15-767x556.png 767w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-15-300x217.png 300w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-15.png 1214w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 id=\"step-2-add-some-styling-without-static-files\" class=\"wp-block-heading\">Step 2: Add Some Styling Without Static Files<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Since we&#8217;re not using Django&#8217;s static file system yet either, the simplest option at this stage is a <code>&lt;style&gt;<\/code> block written directly inside the HTML string:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def home(request):\n    html = \"\"\"\n    &lt;!DOCTYPE html&gt;\n    &lt;html lang=\"en\"&gt;\n    &lt;head&gt;\n        &lt;meta charset=\"UTF-8\"&gt;\n        &lt;title&gt;My Django Site&lt;\/title&gt;\n        &lt;style&gt;\n            body {\n                font-family: sans-serif;\n                margin: 0;\n                padding: 0;\n            }\n            nav {\n                background-color: #222;\n                padding: 1rem;\n            }\n            nav a {\n                color: white;\n                margin-right: 1rem;\n                text-decoration: none;\n            }\n        &lt;\/style&gt;\n    &lt;\/head&gt;\n    &lt;body&gt;\n        &lt;nav&gt;\n            &lt;a href=\"\/\"&gt;Home&lt;\/a&gt;\n            &lt;a href=\"\/about\/\"&gt;About&lt;\/a&gt;\n        &lt;\/nav&gt;\n\n        &lt;main&gt;\n            &lt;h1&gt;Welcome to my site&lt;\/h1&gt;\n            &lt;p&gt;This homepage is built directly inside the view, using HttpResponse.&lt;\/p&gt;\n        &lt;\/main&gt;\n\n        &lt;footer&gt;\n            &lt;p&gt;&amp;copy; 2026 My Django Site&lt;\/p&gt;\n        &lt;\/footer&gt;\n    &lt;\/body&gt;\n    &lt;\/html&gt;\n    \"\"\"\n    return HttpResponse(html)<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"385\" src=\"https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-14-1024x385.png\" alt=\"Django index page tutorial\" class=\"wp-image-1724\" srcset=\"https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-14-1024x385.png 1024w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-14-300x113.png 300w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-14-1536x577.png 1536w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-14-767x288.png 767w, https:\/\/nayananimsara.online\/wp-content\/uploads\/2026\/09\/image-14.png 1581w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 id=\"step-3-making-the-navigation-links-actually-work\" class=\"wp-block-heading\">Step 3: Making the Navigation Links Actually Work<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Notice the nav links point to plain paths \u2014 <code>\/<\/code> and <code>\/about\/<\/code> \u2014 written directly as strings rather than using Django&#8217;s <code>{% url %}<\/code> tag, since that belongs to the template system we haven&#8217;t covered yet. As long as those paths match what&#8217;s defined in your <code>urls.py<\/code>, they&#8217;ll work exactly as expected. If you followed the earlier post on views and URLs, <code>\/about\/<\/code> should already be wired up to an <code>about<\/code> view.<\/p>\n\n\n\n<h2 id=\"where-this-approach-starts-to-break-down\" class=\"wp-block-heading\">Where This Approach Starts to Break Down<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I want to be upfront about the downside here, because it&#8217;s the actual reason templates exist as a feature at all. Every view that returns a full HTML page like this ends up repeating the same <code>&lt;head&gt;<\/code>, the same navigation bar, the same footer. Add a third or fourth page, and you&#8217;re copying that same block of HTML into every single view function. Change one word in your navbar, and you&#8217;d have to update it in every view manually.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That&#8217;s not a mistake at this stage \u2014 it&#8217;s just the natural limit of this method, and it&#8217;s exactly the problem Django&#8217;s template system is built to solve. We&#8217;ll get there. For now, this is a completely valid way to build a working homepage while sticking to what the course has actually covered so far.<\/p>\n\n\n\n<h2 id=\"a-small-practical-tip\" class=\"wp-block-heading\">A Small Practical Tip<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Keep the HTML string readable by matching the indentation of your Python code, the way I did above. It&#8217;s tempting to squeeze everything onto fewer lines once the string gets long, but readable HTML inside a Python string saves you real time the next time you need to find and fix something inside it.<\/p>\n\n\n\n<h2 id=\"where-this-connects-in-the-series\" class=\"wp-block-heading\">Where This Connects in the Series<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This builds directly on the views and URLs you set up in the earlier tutorial \u2014 the <code>about<\/code> link in the navbar above assumes that view already exists. If anything about routing feels unfamiliar here, that post is worth revisiting first. For more on what <code>HttpResponse<\/code> can actually accept as a string, the <a href=\"https:\/\/docs.djangoproject.com\/en\/stable\/ref\/request-response\/#httpresponse-objects\" target=\"_blank\" rel=\"noopener\">official Django documentation on HttpResponse objects<\/a> is worth a look.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Your homepage now has real structure and styling behind it, built entirely through the tools you already know. Once you feel the repetition of copying that navbar into every new view, you&#8217;ll actually understand why templates exist \u2014 which is exactly where this series picks up next.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/nayananimsara.online\/course\/django-course-sinhala\/\" target=\"_blank\" data-type=\"link\" data-id=\"https:\/\/nayananimsara.online\/course\/django-course-sinhala\/\" rel=\"noreferrer noopener\">Our Full Course<\/a><\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<div class=\"tg-oembed-container\"><iframe title=\"WebHD 720p 11\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/nS9ZMKrgS0k?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<\/div><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Create a Django Home Page That Actually Looks Like a Website create a Django home page with navigation and base template By this point in the series, your Django project can respond to a browser request, but if you&#8217;ve been following along, your homepage is still just one line of plain text sitting on a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"elearning_container_layout":"tg-site-layout--default","elearning_sidebar_layout":"tg-site-layout--default","elearning_remove_content_margin":false,"elearning_sidebar":"default","elearning_transparent_header":"customizer","elearning_logo":0,"elearning_header_style":"default","elearning_menu_item_color":"","elearning_menu_item_hover_color":"","elearning_menu_item_active_color":"","elearning_menu_item_active_style":"","elearning_page_header":true,"footnotes":""},"categories":[64],"tags":[],"class_list":["post-1717","post","type-post","status-publish","format-standard","hentry","category-django"],"_links":{"self":[{"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/posts\/1717","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/comments?post=1717"}],"version-history":[{"count":6,"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/posts\/1717\/revisions"}],"predecessor-version":[{"id":1731,"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/posts\/1717\/revisions\/1731"}],"wp:attachment":[{"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/media?parent=1717"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/categories?post=1717"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/tags?post=1717"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}