Chapter 4: Django Add Main Index Page
Grab your coffee, sit comfortably, and let’s build the main index page of your Django project together. It’s around 5:00 PM in Hyderabad on January 31, 2026 — perfect time to make your app feel like a real website instead of just a collection of scattered pages.
Right now you probably have:
- polls/ app with models (Question + Choice)
- Some data in the database
- polls/templates/polls/index.html showing a list of questions
- polls/ urls pointing to /polls/ → polls app index
- A nice base.html master template
But the root URL (http://127.0.0.1:8000/) still shows either:
- the default Django rocket page, or
- 404, or
- nothing meaningful
Today we fix that → we create a proper main/home/index page at / (the domain root), which is what most visitors see first.
We’ll do this in the recommended 2026 way — clean, scalable, and following what most medium-sized Django projects actually do.
Two Realistic Choices for the Main Index Page
| Approach | When people use it | Pros | Cons | Folder name people usually choose |
|---|---|---|---|---|
| Put everything in polls/ app | Very small projects, learning phase | Fewer folders | Becomes messy when you add more features | — |
| Create small pages / core / home app | Almost every real project (most recommended) | Clean separation, conventional | One extra app | pages or core |
| Just TemplateView in project urls | Super-minimal landing page (marketing only) | Fastest possible | Hard to grow (no models/views logic) | — |
Best choice for you right now: Create a tiny app called pages (or core) → this is what ~70–80% of Django developers do in real projects in 2026
Step 1: Create the pages App
In your terminal (inside virtualenv, project root):
|
0 1 2 3 4 5 6 |
python manage.py startapp pages |
Add it to INSTALLED_APPS in mysite/settings.py:
|
0 1 2 3 4 5 6 7 8 9 10 |
INSTALLED_APPS = [ ... 'polls.apps.PollsConfig', 'pages.apps.PagesConfig', # ← add this line ] |
Now folder structure:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
mysite-project/ ├── pages/ │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations/ │ ├── models.py # usually empty for home page │ ├── tests.py │ ├── views.py │ └── urls.py # we create this next ├── polls/ ├── templates/ │ └── base.html └── manage.py |
Step 2: Create pages/urls.py
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# pages/urls.py from django.urls import path from . import views app_name = 'pages' # good habit — prevents name clashes later urlpatterns = [ path('', views.home, name='home'), # root URL '' ] |
Step 3: Create a Simple Home View (Function-Based First)
pages/views.py
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
from django.shortcuts import render def home(request): context = { 'page_title': 'Welcome to Hyderabad Polls', 'welcome_message': 'Ask anything. Get real opinions. No drama.', 'show_polls_link': True, 'current_year': 2026, 'featured_polls_count': 12, # fake number – later real query } return render(request, 'pages/home.html', context) |
(You can also use TemplateView class — we’ll see both)
Step 4: Connect It to Project URLs (Root Route)
Open mysite/urls.py (project level):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), # Polls app path('polls/', include('polls.urls')), # Main home page – IMPORTANT: put '' LAST path('', include('pages.urls')), # ← this catches root / ] |
Order matters Django matches URLs top-to-bottom. If you put path(”, …) first → nothing else would ever match.
Step 5: Create the Home Template (pages/templates/pages/home.html)
First create the folder structure:
|
0 1 2 3 4 5 6 |
mkdir -p pages/templates/pages |
Now pages/templates/pages/home.html:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
{% extends "base.html" %} {% block title %}{{ page_title }}{% endblock %} {% block content %} <div style="text-align: center; padding: 4rem 1rem 6rem;"> <h1 style="font-size: 3.2rem; margin-bottom: 1rem; color: var(--primary);"> {{ page_title }} </h1> <p style="font-size: 1.4rem; color: #444; max-width: 700px; margin: 0 auto 2.5rem;"> {{ welcome_message }} </p> {% if show_polls_link %} <a href="{% url 'polls:index' %}" class="btn" style="font-size: 1.2rem; padding: 1rem 2.2rem;"> Browse Available Polls → </a> {% endif %} <div style="margin-top: 4rem; color: var(--gray);"> <p>Join <strong>{{ featured_polls_count }}</strong> active polls right now</p> <p style="font-size: 0.95rem; margin-top: 2rem;"> Built with Django 6.0 • Made in Hyderabad • {{ current_year }} </p> </div> </div> {% endblock %} |
Step 6: Test It!
|
0 1 2 3 4 5 6 |
python manage.py runserver |
Open: http://127.0.0.1:8000/
You should see:
- Your nice header from base.html
- Big welcome title
- Message
- Button linking to /polls/
- Footer
→ No more rocket page! This is now your real homepage.
Bonus: Class-Based View Version (Many Teams Prefer This)
Alternative pages/views.py:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
from django.views.generic import TemplateView class HomeView(TemplateView): template_name = 'pages/home.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context.update({ 'page_title': 'Welcome to Hyderabad Polls', 'welcome_message': 'Real questions. Real answers.', 'show_polls_link': True, 'featured_polls_count': 15, }) return context |
Then in pages/urls.py:
|
0 1 2 3 4 5 6 |
path('', HomeView.as_view(), name='home'), |
Same result — just more reusable when you want to add login checks, featured polls query, etc.
Quick Summary – What We Did
- Created small pages app
- Added simple home view
- Created namespaced pages/home.html
- Connected root URL ” to pages.urls
- Extended base.html → consistent design
- Added nice call-to-action button to polls
Common Mistakes & Quick Fixes
- 404 at root → Forgot path(”, include(‘pages.urls’)) or put it before admin/
- TemplateDoesNotExist: pages/home.html → Wrong folder → must be pages/templates/pages/home.html
- NoReverseMatch for ‘polls:index’ → Forgot app_name = ‘polls’ in polls/urls.py
- Old rocket page still shows → Check URL order — root path must be last
Your Mini Homework
- Create the pages app & home page exactly as shown
- Visit / → make sure it looks good
- Click the “Browse Available Polls” button → should go to /polls/
- (Optional) Add one nice hero image or statistic in the template
Tell me what feels next:
- “It works! Now show me how to add a real featured polls section on home”
- “How to make different homepage for logged-in vs anonymous users?”
- “I want a more marketing-style landing page (hero + testimonials)”
- “Got error – here is message/screenshot”
- Or finally ready for: “Let’s implement voting form + POST + vote counting”
You’ve just created the front door of your app — visitors will see this first. You’re doing really well — let’s make it even better! 🚀🇮🇳
