Creating your first "Hello World" application in Django demonstrates the fundamental concepts of views, URLs, and templates. This guide walks you through building a simple but complete Django application from scratch.
Before starting, ensure you have:
Verify Your Setup:
# Activate virtual environment
source django_env/bin/activate
# Navigate to your project
cd mysite
# Test server startup
python manage.py runserver
The quickest way to create a "Hello World" page is with a simple HTTP response.
Create or edit mysite/views.py:
# mysite/views.py
from django.http import HttpResponse
from django.utils import timezone
def hello_world(request):
"""Simple Hello World view"""
return HttpResponse("<h1>Hello, World!</h1><p>Welcome to Django!</p>")
def hello_user(request):
"""Dynamic Hello World with user info"""
user_agent = request.META.get('HTTP_USER_AGENT', 'Unknown')
current_time = timezone.now().strftime('%Y-%m-%d %H:%M:%S')
html = f"""
<html>
<head>
<title>Hello World</title>
<style>
body {{ font-family: Arial, sans-serif; margin: 40px; }}
.info {{ background: #f0f0f0; padding: 20px; border-radius: 5px; }}
</style>
</head>
<body>
<h1>Hello, World!</h1>
<div class="info">
<p><strong>Current Time:</strong> {current_time}</p>
<p><strong>Your Browser:</strong> {user_agent}</p>
<p><strong>Request Method:</strong> {request.method}</p>
</div>
</body>
</html>
"""
return HttpResponse(html)
Update mysite/urls.py:
# mysite/urls.py
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.hello_world, name='hello_world'),
path('hello/', views.hello_user, name='hello_user'),
]
# Start the development server
python manage.py runserver
# Visit in your browser:
# http://127.0.0.1:8000/ - Simple hello world
# http://127.0.0.1:8000/hello/ - Dynamic hello world
Templates provide better separation of concerns and are the Django way of handling presentation.
# Create templates directory in your project root
mkdir -p templates
Update mysite/settings.py:
# mysite/settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], # Add this line
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Create templates/base.html:
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Django Hello World{% endblock %}</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.container {
background: white;
padding: 40px;
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
text-align: center;
max-width: 600px;
width: 90%;
}
h1 {
color: #333;
margin-bottom: 20px;
font-size: 2.5em;
}
.info-box {
background: #f8f9fa;
padding: 20px;
border-radius: 5px;
margin: 20px 0;
text-align: left;
}
.info-box h3 {
margin-top: 0;
color: #495057;
}
.highlight {
background: #fff3cd;
padding: 10px;
border-left: 4px solid #ffc107;
margin: 10px 0;
}
.nav-links {
margin-top: 30px;
}
.nav-links a {
display: inline-block;
margin: 0 10px;
padding: 10px 20px;
background: #007bff;
color: white;
text-decoration: none;
border-radius: 5px;
transition: background 0.3s;
}
.nav-links a:hover {
background: #0056b3;
}
</style>
{% block extra_css %}{% endblock %}
</head>
<body>
<div class="container">
{% block content %}{% endblock %}
<div class="nav-links">
<a href="{% url 'hello_world' %}">Simple Hello</a>
<a href="{% url 'hello_template' %}">Template Hello</a>
<a href="{% url 'hello_dynamic' %}">Dynamic Hello</a>
<a href="{% url 'admin:index' %}">Admin</a>
</div>
</div>
{% block extra_js %}{% endblock %}
</body>
</html>
Create templates/hello_world.html:
<!-- templates/hello_world.html -->
{% extends 'base.html' %}
{% block title %}Hello World - {{ block.super }}{% endblock %}
{% block content %}
<h1>🌍 Hello, World!</h1>
<p>Welcome to your first Django application!</p>
<div class="info-box">
<h3>What you've accomplished:</h3>
<ul>
<li>✅ Created a Django project</li>
<li>✅ Set up URL routing</li>
<li>✅ Built your first view</li>
<li>✅ Used Django templates</li>
<li>✅ Applied CSS styling</li>
</ul>
</div>
<div class="highlight">
<strong>Congratulations!</strong> You're now ready to build amazing web applications with Django.
</div>
{% endblock %}
Create templates/hello_dynamic.html:
<!-- templates/hello_dynamic.html -->
{% extends 'base.html' %}
{% block title %}Dynamic Hello - {{ block.super }}{% endblock %}
{% block content %}
<h1>👋 Hello, {{ name|default:"Visitor" }}!</h1>
<div class="info-box">
<h3>Request Information:</h3>
<p><strong>Current Time:</strong> {{ current_time }}</p>
<p><strong>Request Method:</strong> {{ request.method }}</p>
<p><strong>User Agent:</strong> {{ user_agent|truncatechars:50 }}</p>
<p><strong>Remote Address:</strong> {{ remote_addr }}</p>
</div>
<div class="info-box">
<h3>Django Context Variables:</h3>
<p><strong>Debug Mode:</strong> {{ debug }}</p>
<p><strong>Language Code:</strong> {{ LANGUAGE_CODE }}</p>
<p><strong>Time Zone:</strong> {{ TIME_ZONE }}</p>
</div>
{% if user.is_authenticated %}
<div class="highlight">
<strong>Welcome back, {{ user.username }}!</strong> You are logged in.
</div>
{% else %}
<div class="highlight">
You are browsing as an anonymous user.
<a href="{% url 'admin:index' %}">Login here</a> to see personalized content.
</div>
{% endif %}
{% endblock %}
Update mysite/views.py:
# mysite/views.py
from django.http import HttpResponse
from django.shortcuts import render
from django.utils import timezone
from django.conf import settings
import socket
def hello_world(request):
"""Simple Hello World view with HttpResponse"""
return HttpResponse("<h1>Hello, World!</h1><p>This is a simple HTTP response.</p>")
def hello_template(request):
"""Hello World using templates"""
return render(request, 'hello_world.html')
def hello_dynamic(request):
"""Dynamic Hello World with context data"""
# Get client IP address
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
context = {
'name': request.GET.get('name', ''),
'current_time': timezone.now(),
'user_agent': request.META.get('HTTP_USER_AGENT', 'Unknown'),
'remote_addr': ip,
'debug': settings.DEBUG,
}
return render(request, 'hello_dynamic.html', context)
def hello_json(request):
"""Hello World as JSON response"""
from django.http import JsonResponse
data = {
'message': 'Hello, World!',
'timestamp': timezone.now().isoformat(),
'method': request.method,
'success': True,
'django_version': '4.2.7'
}
return JsonResponse(data)
def hello_with_params(request, name):
"""Hello World with URL parameters"""
context = {
'name': name.title(),
'current_time': timezone.now(),
}
return render(request, 'hello_dynamic.html', context)
Update mysite/urls.py:
# mysite/urls.py
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.hello_template, name='hello_world'),
path('simple/', views.hello_world, name='hello_simple'),
path('template/', views.hello_template, name='hello_template'),
path('dynamic/', views.hello_dynamic, name='hello_dynamic'),
path('json/', views.hello_json, name='hello_json'),
path('hello/<str:name>/', views.hello_with_params, name='hello_params'),
]
For larger projects, create a dedicated app for better organization.
python manage.py startapp hello
Add to INSTALLED_APPS in mysite/settings.py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'hello', # Add your new app
]
Update hello/views.py:
# hello/views.py
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from django.utils import timezone
from django.views.generic import TemplateView
from django.views import View
def index(request):
"""Main hello world page"""
return render(request, 'hello/index.html')
class HelloWorldView(TemplateView):
"""Class-based view for Hello World"""
template_name = 'hello/class_based.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({
'message': 'Hello from Class-Based View!',
'timestamp': timezone.now(),
'view_type': 'Class-Based View (CBV)'
})
return context
class HelloAPIView(View):
"""API endpoint for Hello World"""
def get(self, request):
data = {
'message': 'Hello, World!',
'method': 'GET',
'timestamp': timezone.now().isoformat(),
'endpoints': {
'hello': '/hello/',
'api': '/hello/api/',
'cbv': '/hello/cbv/',
}
}
return JsonResponse(data)
def post(self, request):
name = request.POST.get('name', 'World')
data = {
'message': f'Hello, {name}!',
'method': 'POST',
'timestamp': timezone.now().isoformat(),
}
return JsonResponse(data)
Create template directories:
mkdir -p hello/templates/hello
Create hello/templates/hello/index.html:
<!-- hello/templates/hello/index.html -->
{% extends 'base.html' %}
{% block title %}Hello App - {{ block.super }}{% endblock %}
{% block content %}
<h1>🚀 Hello World App</h1>
<p>This is a dedicated Django app for Hello World functionality.</p>
<div class="info-box">
<h3>App Features:</h3>
<ul>
<li>Function-based views</li>
<li>Class-based views</li>
<li>API endpoints</li>
<li>Template inheritance</li>
<li>URL namespacing</li>
</ul>
</div>
<div class="nav-links">
<a href="{% url 'hello:cbv' %}">Class-Based View</a>
<a href="{% url 'hello:api' %}">API Endpoint</a>
</div>
{% endblock %}
Create hello/templates/hello/class_based.html:
<!-- hello/templates/hello/class_based.html -->
{% extends 'base.html' %}
{% block title %}{{ view_type }} - {{ block.super }}{% endblock %}
{% block content %}
<h1>{{ message }}</h1>
<div class="info-box">
<h3>View Information:</h3>
<p><strong>View Type:</strong> {{ view_type }}</p>
<p><strong>Timestamp:</strong> {{ timestamp }}</p>
<p><strong>Template:</strong> hello/class_based.html</p>
</div>
<div class="highlight">
This page was rendered using Django's Class-Based Views (CBV),
which provide a more object-oriented approach to handling requests.
</div>
{% endblock %}
Create hello/urls.py:
# hello/urls.py
from django.urls import path
from . import views
app_name = 'hello'
urlpatterns = [
path('', views.index, name='index'),
path('cbv/', views.HelloWorldView.as_view(), name='cbv'),
path('api/', views.HelloAPIView.as_view(), name='api'),
]
Update main mysite/urls.py:
# mysite/urls.py
from django.contrib import admin
from django.urls import path, include
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.hello_template, name='hello_world'),
path('simple/', views.hello_world, name='hello_simple'),
path('template/', views.hello_template, name='hello_template'),
path('dynamic/', views.hello_dynamic, name='hello_dynamic'),
path('json/', views.hello_json, name='hello_json'),
path('hello/<str:name>/', views.hello_with_params, name='hello_params'),
path('hello/', include('hello.urls')), # Include app URLs
]
Visit these URLs in your browser:
Test the JSON endpoint:
# GET request
curl http://127.0.0.1:8000/json/
# POST request to app API
curl -X POST -d "name=Django" http://127.0.0.1:8000/hello/api/
Create hello/tests.py:
# hello/tests.py
from django.test import TestCase, Client
from django.urls import reverse
from django.utils import timezone
import json
class HelloWorldTests(TestCase):
def setUp(self):
self.client = Client()
def test_simple_hello_world(self):
"""Test simple HTTP response view"""
response = self.client.get(reverse('hello_simple'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Hello, World!')
def test_template_hello_world(self):
"""Test template-based view"""
response = self.client.get(reverse('hello_template'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Hello, World!')
self.assertTemplateUsed(response, 'hello_world.html')
def test_dynamic_hello_world(self):
"""Test dynamic view with parameters"""
response = self.client.get(reverse('hello_dynamic'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Hello, Visitor!')
# Test with name parameter
response = self.client.get(reverse('hello_dynamic') + '?name=Django')
self.assertContains(response, 'Hello, Django!')
def test_json_api(self):
"""Test JSON API endpoint"""
response = self.client.get(reverse('hello_json'))
self.assertEqual(response.status_code, 200)
self.assertEqual(response['Content-Type'], 'application/json')
data = json.loads(response.content)
self.assertEqual(data['message'], 'Hello, World!')
self.assertTrue(data['success'])
def test_url_parameters(self):
"""Test URL parameter handling"""
response = self.client.get(reverse('hello_params', args=['Django']))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Hello, Django!')
def test_hello_app_views(self):
"""Test dedicated app views"""
# Test app index
response = self.client.get(reverse('hello:index'))
self.assertEqual(response.status_code, 200)
# Test class-based view
response = self.client.get(reverse('hello:cbv'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Class-Based View')
# Test API view
response = self.client.get(reverse('hello:api'))
self.assertEqual(response.status_code, 200)
data = json.loads(response.content)
self.assertIn('endpoints', data)
Run the tests:
python manage.py test
Function-Based Views (FBV):
def hello_world(request):
# Simple, straightforward
# Good for simple logic
return HttpResponse("Hello, World!")
Class-Based Views (CBV):
class HelloWorldView(TemplateView):
# More structured, reusable
# Good for complex logic
template_name = 'hello.html'
urlpatterns = [
# Static URL
path('hello/', views.hello_world, name='hello'),
# Dynamic URL with parameter
path('hello/<str:name>/', views.hello_user, name='hello_user'),
# Include app URLs with namespace
path('app/', include('hello.urls')),
]
def my_view(request):
context = {
'variable_name': 'value', # Available as {{ variable_name }}
'list_data': [1, 2, 3], # Available as {{ list_data }}
'dict_data': {'key': 'value'}, # Available as {{ dict_data.key }}
}
return render(request, 'template.html', context)
{% extends %}Problem: TemplateDoesNotExist error
Solution:
# Check TEMPLATES setting in settings.py
TEMPLATES = [
{
'DIRS': [BASE_DIR / 'templates'], # Ensure this is set
'APP_DIRS': True, # Ensure this is True
}
]
Problem: NoReverseMatch error
Solution:
# Ensure URL names match
path('hello/', views.hello, name='hello_world')
# Use correct name in templates
{% url 'hello_world' %}
# Use namespaces for app URLs
{% url 'hello:index' %}
Problem: CSS/JS not loading Solution:
# In settings.py
STATIC_URL = '/static/'
# In templates
{% load static %}
<link rel="stylesheet" href="{% static 'css/style.css' %}">
Problem: Variables not showing in templates Solution:
# Ensure context is passed correctly
def my_view(request):
context = {'my_var': 'value'}
return render(request, 'template.html', context) # Don't forget context!
Now that you have a working "Hello World" application:
Congratulations! You've successfully created your first Django application with multiple approaches, demonstrating the flexibility and power of the Django framework.
Creating Your First Django App
In Django, a project is the entire web application, while an app is a specific component that handles a particular functionality. Apps are designed to be reusable and modular, following Django's philosophy of loose coupling and high cohesion.
Django Quick Start Guide
This guide gets you from zero to a working Django application in under 30 minutes. Perfect for developers who want to see Django in action quickly or need a rapid refresher on Django fundamentals.