Getting Started with Django: Build Your First Web App

A step-by-step interactive tutorial for complete beginners

Estimated time: 90 minutes

1. Introduction to Django

What is Django?

Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. It takes care of much of the hassle of web development, so you can focus on writing your app without needing to reinvent the wheel.

Django follows the "batteries-included" philosophy and provides almost everything developers might want to do "out of the box". Because everything you need is part of the one "product", it all works seamlessly together, follows consistent design principles, and has extensive and up-to-date documentation.

Why Django?

  • Ridiculously fast - Django was designed to help developers take applications from concept to completion as quickly as possible.
  • Reassuringly secure - Django takes security seriously and helps developers avoid many common security mistakes.
  • Exceedingly scalable - Some of the busiest sites on the web use Django to handle their heaviest traffic demands.
  • Incredibly versatile - Companies, organizations, and governments have used Django to build all sorts of things—from content management systems to social networks to scientific computing platforms.

Django's Architecture

Django follows the Model-View-Template (MVT) architectural pattern, a variant of the classic Model-View-Controller (MVC) pattern:

Model

Data structure & database

View

Business logic & data processing

Template

Presentation & display logic

URLs

Routing & mapping

Quick Quiz: Django Basics

Test your understanding of Django's basics:

Which architectural pattern does Django follow?

Model-View-Template (MVT)
Model-View-Controller (MVC)
View-Template-Controller (VTC)
Template-Model-View (TMV)
Correct! Django follows the MVT (Model-View-Template) pattern, which is similar to MVC but with some Django-specific terminology.
Not quite. Django follows the MVT (Model-View-Template) pattern, which is similar to MVC but with some Django-specific terminology.
What we'll build: In this tutorial, we'll create a simple note-taking application where users can create, view, and list notes. Each note will have a title and body content.

2. Setting Up Your Environment

Before we can start building our Django application, we need to set up our development environment. This includes installing Python, creating a virtual environment, and installing Django.

Install Python

Django is a Python framework, so we need to install Python first. Django 4.0+ requires Python 3.8 or higher.

  • Download Python from python.org/downloads
  • During installation, make sure to check "Add Python to PATH"

Verify your installation by opening a terminal or command prompt and typing:

python --version

You should see something like Python 3.10.0 (your version may differ).

Create a Virtual Environment

Virtual environments allow you to have isolated Python environments for different projects, so their dependencies don't interfere with each other.

Open a terminal and navigate to where you want to create your project:

cd path/to/your/projects/folder

Create a new directory for your project:

mkdir mynotes
cd mynotes

Create a virtual environment:

Windows
Mac/Linux
python -m venv venv
python3 -m venv venv

Activate the virtual environment:

Windows
Mac/Linux
venv\Scripts\activate
source venv/bin/activate

You'll know your virtual environment is active when you see (venv) at the beginning of your command prompt.

Install Django

With your virtual environment activated, install Django:

pip install django

Verify the installation:

python -m django --version

You should see the Django version number, like 4.2.1 (your version may differ).

Pro Tip: Always activate your virtual environment before working on your project. If you close your terminal and come back later, you'll need to activate it again.

Quick Quiz: Virtual Environments

Why should you use a virtual environment for your Django projects?

To make your code run faster
To isolate project dependencies and avoid conflicts
To make your project compatible with all operating systems
To enable Django's security features
Correct! Virtual environments isolate dependencies for different projects, preventing conflicts between them.
Not quite. Virtual environments are used to isolate project dependencies and prevent conflicts between different projects that might require different versions of the same packages.

3. Creating a Django Project and App

In Django, a project is the entire web application, while an app is a module within the project that handles a specific functionality. A project can contain multiple apps.

Create a Django Project

With your virtual environment activated, run:

django-admin startproject mynotes .

Note the dot . at the end, which tells Django to create the project in the current directory instead of creating a new directory.

Create a Django App

Now, let's create an app within our project:

python manage.py startapp notes

Register the App

Open the mynotes/settings.py file and add your app to the INSTALLED_APPS list:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'notes',  # Add this line
]

Run Initial Migrations

Django uses migrations to keep track of changes to your models and update the database schema accordingly. Let's run the initial migrations:

python manage.py migrate

This applies the built-in migrations for the default apps listed in INSTALLED_APPS.

Start the Development Server

Let's verify everything is working by starting the development server:

python manage.py runserver

Open a web browser and navigate to http://127.0.0.1:8000/. You should see the Django welcome page.

Press CTRL+C in the terminal to stop the server when you're done.

Note: Never use the development server in a production environment. It's not designed to be particularly secure, stable, or efficient.

Quick Quiz: Projects vs Apps

What is the relationship between Django projects and apps?

Projects and apps are the same thing
Projects are made up of multiple websites, each containing one app
A project can contain multiple apps, each handling specific functionality
Apps are standalone and can't be part of a project
Correct! A Django project is the entire web application, which can contain multiple apps that each handle specific functionality.
Not quite. A Django project represents the entire web application and can contain multiple apps, each handling a specific functionality or feature of the website.

4. Understanding Django Folder Structure

Let's explore the directory structure Django has created for us and understand what each file does.

mynotes/ (project root)
manage.py - Command-line utility for administrative tasks
mynotes/ (project package)
__init__.py - Empty file that makes the directory a Python package
settings.py - Project settings/configuration
urls.py - URL declarations for the project
asgi.py - ASGI configuration for async web servers
wsgi.py - WSGI configuration for traditional web servers
notes/ (app package)
__init__.py - Makes the directory a Python package
admin.py - Configuration for the Django admin interface
apps.py - App configuration
models.py - Data models definition
tests.py - Testing functions
views.py - Request handlers
urls.py - URL declarations for the app (we'll create this)
migrations/
__init__.py - Makes the directory a Python package
templates/ (we'll create this)
notes/ (we'll create this)
base.html - Base template (we'll create this)
home.html - Homepage template (we'll create this)
note_list.html - Note list template (we'll create this)
note_form.html - Note form template (we'll create this)

Key Files and Their Purposes

  • manage.py: A command-line utility that lets you interact with your Django project. You'll use it to run the server, create migrations, apply migrations, and more.
  • settings.py: Contains all the project settings, including database configuration, installed apps, middleware, and more.
  • urls.py: A "table of contents" for your Django site, mapping URLs to views.
  • models.py: Defines your data models, which Django converts to database tables.
  • views.py: Contains view functions or classes that process requests and return responses.
  • admin.py: Configuration for the built-in Django admin interface.
Project vs. App Directory: Notice that Django created a directory with the same name as your project (mynotes/). This can be confusing at first. The outer mynotes/ is your project container, while the inner mynotes/ is a Python package containing your project's settings.

Quick Quiz: Django Files

Which file defines the data models that Django will convert to database tables?

views.py
settings.py
models.py
admin.py
Correct! The models.py file is where you define your data models, which Django converts to database tables.
Not quite. The models.py file is where you define your data models, which Django converts to database tables.

5. Creating a Model and Database Migration

Models are the single, definitive source of information about your data. They contain the essential fields and behaviors of the data you're storing. In our note-taking app, we need a model to represent a note.

Define the Note Model

Open notes/models.py and add the following code:

from django.db import models
from django.utils import timezone

class Note(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return self.title

This code:

  • Creates a Note model with title, content, and created_at fields
  • Sets the created_at field to default to the current date and time
  • Defines a __str__ method that returns the title when the object is converted to a string

Create and Apply Migrations

Migrations are Django's way of propagating changes you make to your models into your database schema. First, we create a migration file:

python manage.py makemigrations notes

This creates a migration file in the notes/migrations/ directory. Now, apply the migration to update the database:

python manage.py migrate

Register the Model with Admin

Django comes with a built-in admin interface that we can use to manage our data. Let's register our model with it.

Open notes/admin.py and add the following code:

from django.contrib import admin
from .models import Note

admin.site.register(Note)

Create a Superuser

To access the admin interface, we need to create a superuser account:

python manage.py createsuperuser

Follow the prompts to create a username, email, and password.

Explore the Admin Interface

Start the development server:

python manage.py runserver

Visit http://127.0.0.1:8000/admin/ and log in with the superuser credentials you just created.

You should see the Django admin interface with your Notes model listed. Try adding a few notes to test it out.

Model-Database Relationship

models.py

Define Note model

makemigrations

Create migration files

migrate

Apply to database

Database

Tables created/updated

Quick Quiz: Django Models

After changing a model, what two commands do you need to run to update the database?

python manage.py createsuperuser and python manage.py runserver
python manage.py makemigrations and python manage.py migrate
python manage.py startapp and python manage.py makemigrations
python manage.py migrate and python manage.py createsuperuser
Correct! First, you run makemigrations to create the migration files, then migrate to apply them to the database.
Not quite. The correct sequence is: first run makemigrations to create the migration files, then migrate to apply them to the database.

6. Creating Views, Templates, and URLs

Now that we have our model set up, we need to create views, templates, and URLs to display our notes to users.

Create Templates Directory

First, create a directory structure for your templates:

mkdir -p notes/templates/notes

Django looks for templates in a "templates" directory within each app. We add an extra "notes" directory inside the templates directory to namespace our templates and avoid conflicts with other apps.

Create Base Template

Create a base template at notes/templates/notes/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 %}My Notes App{% endblock %}</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <div class="container">
            <a class="navbar-brand" href="{% url 'home' %}">My Notes</a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNav">
                <ul class="navbar-nav">
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'home' %}">Home</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'note_list' %}">All Notes</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'note_new' %}">New Note</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>

    <div class="container mt-4">
        {% block content %}
        {% endblock %}
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

This base template includes Bootstrap for styling and defines blocks that child templates will fill in.

Create Home Template

Create notes/templates/notes/home.html:

{% extends 'notes/base.html' %}

{% block title %}Home | My Notes App{% endblock %}

{% block content %}
<div class="jumbotron">
    <h1 class="display-4">Welcome to My Notes App</h1>
    <p class="lead">A simple Django application to manage your notes.</p>
    <hr class="my-4">
    <p>Get started by creating a new note or viewing your existing notes.</p>
    <a class="btn btn-primary btn-lg" href="{% url 'note_new' %}" role="button">Create New Note</a>
    <a class="btn btn-secondary btn-lg" href="{% url 'note_list' %}" role="button">View All Notes</a>
</div>
{% endblock %}

Create Note List Template

Create notes/templates/notes/note_list.html:

{% extends 'notes/base.html' %}

{% block title %}All Notes | My Notes App{% endblock %}

{% block content %}
<h1>All Notes</h1>

{% if notes %}
    <div class="row">
        {% for note in notes %}
            <div class="col-md-4 mb-4">
                <div class="card">
                    <div class="card-body">
                        <h5 class="card-title">{{ note.title }}</h5>
                        <p class="card-text">{{ note.content|truncatechars:100 }}</p>
                        <p class="text-muted">Created: {{ note.created_at|date:"F j, Y" }}</p>
                    </div>
                </div>
            </div>
        {% endfor %}
    </div>
{% else %}
    <p>No notes yet. <a href="{% url 'note_new' %}">Create one</a>!</p>
{% endif %}
{% endblock %}

Create Views

Open notes/views.py and add the following code:

from django.shortcuts import render
from .models import Note

def home(request):
    return render(request, 'notes/home.html')

def note_list(request):
    notes = Note.objects.all().order_by('-created_at')
    return render(request, 'notes/note_list.html', {'notes': notes})

This creates two views: one for the home page and one for the note list page.

Create App URLs

Create a new file notes/urls.py:

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('notes/', views.note_list, name='note_list'),
]

Include App URLs in Project URLs

Open mynotes/urls.py and modify it:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('notes.urls')),
]

This includes our app's URLs in the project's URL configuration.

Test Your Views

Start the development server:

python manage.py runserver

Visit http://127.0.0.1:8000/ to see the home page and http://127.0.0.1:8000/notes/ to see the note list.

Note: The "New Note" link won't work yet because we haven't created the view for it. We'll do that in the next section.

Django's MVT Flow

URL

User requests a URL

View

Processes the request

Model

Interacts with database

Template

Renders HTML

Response

Returns to user

Quick Quiz: Django Templates

What template tag is used to inherit from a base template?

{% include 'base.html' %}
{% extends 'base.html' %}
{% load 'base.html' %}
{% inherit 'base.html' %}
Correct! The {% extends %} tag is used to inherit from a base template.
Not quite. The {% extends %} tag is used to inherit from a base template.

7. Adding Forms to Create New Notes

Now, let's create a form to allow users to add new notes to our application.

Create a Form

Create a new file notes/forms.py:

from django import forms
from .models import Note

class NoteForm(forms.ModelForm):
    class Meta:
        model = Note
        fields = ['title', 'content']
        widgets = {
            'title': forms.TextInput(attrs={'class': 'form-control'}),
            'content': forms.Textarea(attrs={'class': 'form-control', 'rows': 5}),
        }

This creates a form based on our Note model with fields for title and content. We also add Bootstrap classes to style the form.

Create a Template for the Form

Create notes/templates/notes/note_form.html:

{% extends 'notes/base.html' %}

{% block title %}New Note | My Notes App{% endblock %}

{% block content %}
<h1>{% if form.instance.id %}Edit Note{% else %}New Note{% endif %}</h1>

<form method="post">
    {% csrf_token %}
    <div class="mb-3">
        <label for="{{ form.title.id_for_label }}" class="form-label">Title</label>
        {{ form.title }}
        {% if form.title.errors %}
            <div class="text-danger">{{ form.title.errors }}</div>
        {% endif %}
    </div>

    <div class="mb-3">
        <label for="{{ form.content.id_for_label }}" class="form-label">Content</label>
        {{ form.content }}
        {% if form.content.errors %}
            <div class="text-danger">{{ form.content.errors }}</div>
        {% endif %}
    </div>

    <button type="submit" class="btn btn-primary">Save</button>
    <a href="{% url 'note_list' %}" class="btn btn-secondary">Cancel</a>
</form>
{% endblock %}

Add View for Creating Notes

Update notes/views.py to add a view for creating notes:

from django.shortcuts import render, redirect
from .models import Note
from .forms import NoteForm

def home(request):
    return render(request, 'notes/home.html')

def note_list(request):
    notes = Note.objects.all().order_by('-created_at')
    return render(request, 'notes/note_list.html', {'notes': notes})

def note_new(request):
    if request.method == "POST":
        form = NoteForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('note_list')
    else:
        form = NoteForm()
    return render(request, 'notes/note_form.html', {'form': form})

This adds a new view that:

  • Shows an empty form when the page is first loaded (GET request)
  • Processes the form data when it's submitted (POST request)
  • Redirects to the note list page after successfully saving the note

Update URLs

Update notes/urls.py to add the URL for creating notes:

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('notes/', views.note_list, name='note_list'),
    path('notes/new/', views.note_new, name='note_new'),
]

Test the Form

Start the development server:

python manage.py runserver

Visit http://127.0.0.1:8000/notes/new/ to see the form for creating a new note.

Try creating a new note and verify that it appears in the note list.

Django Forms Security: The {% csrf_token %} in our form template is important for security. It adds a Cross-Site Request Forgery token that helps protect against certain types of attacks.

Quick Quiz: Django Forms

When creating a form based on a model, which class should you inherit from?

forms.Form
forms.ModelForm
models.Form
models.ModelForm
Correct! When creating a form based on a model, you should inherit from forms.ModelForm.
Not quite. When creating a form based on a model, you should inherit from forms.ModelForm, which provides functionality for creating forms directly from your models.

8. Styling with Bootstrap

We've already included Bootstrap in our base template, but let's enhance the styling a bit more to make our app look more polished.

Update the Base Template

Let's add some custom CSS to our base template. Update notes/templates/notes/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 %}My Notes App{% endblock %}</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        body {
            padding-bottom: 2rem;
            background-color: #f8f9fa;
        }
        .navbar {
            margin-bottom: 2rem;
            box-shadow: 0 2px 4px rgba(0,0,0,.1);
        }
        .card {
            box-shadow: 0 2px 5px rgba(0,0,0,.1);
            transition: all 0.3s ease;
        }
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 5px 15px rgba(0,0,0,.15);
        }
        .jumbotron {
            background-color: #ffffff;
            border-radius: 0.5rem;
            padding: 2rem;
            box-shadow: 0 2px 5px rgba(0,0,0,.1);
        }
        .footer {
            margin-top: 3rem;
            padding-top: 1.5rem;
            padding-bottom: 1.5rem;
            background-color: #343a40;
            color: #ffffff;
        }
    </style>
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <div class="container">
            <a class="navbar-brand" href="{% url 'home' %}">
                <i class="fas fa-sticky-note me-2"></i>My Notes
            </a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNav">
                <ul class="navbar-nav">
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'home' %}">Home</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'note_list' %}">All Notes</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'note_new' %}">New Note</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>

    <div class="container mt-4">
        {% block content %}
        {% endblock %}
    </div>

    <footer class="footer mt-auto">
        <div class="container text-center">
            <p>My Notes App - Built with Django</p>
        </div>
    </footer>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.4/js/all.min.js"></script>
</body>
</html>

Update the Note List Template

Enhance notes/templates/notes/note_list.html:

{% extends 'notes/base.html' %}

{% block title %}All Notes | My Notes App{% endblock %}

{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
    <h1>All Notes</h1>
    <a href="{% url 'note_new' %}" class="btn btn-primary">
        <i class="fas fa-plus me-2"></i>New Note
    </a>
</div>

{% if notes %}
    <div class="row">
        {% for note in notes %}
            <div class="col-md-4 mb-4">
                <div class="card h-100">
                    <div class="card-header bg-light d-flex justify-content-between align-items-center">
                        <span class="text-muted">{{ note.created_at|date:"F j, Y" }}</span>
                    </div>
                    <div class="card-body">
                        <h5 class="card-title">{{ note.title }}</h5>
                        <p class="card-text">{{ note.content|truncatechars:100 }}</p>
                    </div>
                </div>
            </div>
        {% endfor %}
    </div>
{% else %}
    <div class="alert alert-info">
        <i class="fas fa-info-circle me-2"></i>No notes yet. <a href="{% url 'note_new' %}" class="alert-link">Create one</a>!
    </div>
{% endif %}
{% endblock %}

Update the Home Template

Enhance notes/templates/notes/home.html:

{% extends 'notes/base.html' %}

{% block title %}Home | My Notes App{% endblock %}

{% block content %}
<div class="jumbotron text-center">
    <h1 class="display-4 mb-4">Welcome to My Notes App</h1>
    <p class="lead">A simple Django application to manage your notes</p>
    <hr class="my-4">
    <div class="row mt-5 justify-content-center">
        <div class="col-md-4 mb-4">
            <div class="card text-center h-100">
                <div class="card-body">
                    <i class="fas fa-plus-circle fa-4x mb-3 text-success"></i>
                    <h3 class="card-title">Create</h3>
                    <p class="card-text">Create new notes with titles and content</p>
                    <a href="{% url 'note_new' %}" class="btn btn-success">New Note</a>
                </div>
            </div>
        </div>
        <div class="col-md-4 mb-4">
            <div class="card text-center h-100">
                <div class="card-body">
                    <i class="fas fa-list-ul fa-4x mb-3 text-primary"></i>
                    <h3 class="card-title">View</h3>
                    <p class="card-text">View all your saved notes in one place</p>
                    <a href="{% url 'note_list' %}" class="btn btn-primary">View Notes</a>
                </div>
            </div>
        </div>
    </div>
</div>
{% endblock %}

Update the Form Template

Enhance notes/templates/notes/note_form.html:

{% extends 'notes/base.html' %}

{% block title %}New Note | My Notes App{% endblock %}

{% block content %}
<div class="card">
    <div class="card-header">
        <h2>{% if form.instance.id %}Edit Note{% else %}New Note{% endif %}</h2>
    </div>
    <div class="card-body">
        <form method="post">
            {% csrf_token %}
            <div class="mb-3">
                <label for="{{ form.title.id_for_label }}" class="form-label">Title</label>
                {{ form.title }}
                {% if form.title.errors %}
                    <div class="text-danger">{{ form.title.errors }}</div>
                {% endif %}
            </div>

            <div class="mb-3">
                <label for="{{ form.content.id_for_label }}" class="form-label">Content</label>
                {{ form.content }}
                {% if form.content.errors %}
                    <div class="text-danger">{{ form.content.errors }}</div>
                {% endif %}
            </div>

            <div class="d-flex mt-4">
                <button type="submit" class="btn btn-primary me-2">
                    <i class="fas fa-save me-2"></i>Save
                </button>
                <a href="{% url 'note_list' %}" class="btn btn-secondary">
                    <i class="fas fa-times me-2"></i>Cancel
                </a>
            </div>
        </form>
    </div>
</div>
{% endblock %}

Test the Styled App

Start the development server:

python manage.py runserver

Visit http://127.0.0.1:8000/ to see your beautifully styled app.

Styling Tip: Bootstrap provides many components and utilities out of the box, but you can always add custom CSS to tailor the appearance to your specific needs. Add your custom styles in the <style> section of the base template or in a separate CSS file.

9. Running and Testing the App

Let's make sure our application is working correctly and test all the features we've implemented.

Run the Development Server

Start the development server:

python manage.py runserver

The server will start at http://127.0.0.1:8000/

Test the Home Page

Visit the home page and verify that it displays correctly with links to create and view notes.

Ensure that the "New Note" and "View Notes" buttons work correctly.

Test Creating a Note

Click on "New Note" and create a note with a title and content.

Submit the form and verify that you are redirected to the note list page and that your new note appears in the list.

Test the Note List

Visit the note list page and verify that all your notes are displayed correctly.

Create multiple notes and ensure they all appear in the list.

Test the Navigation

Verify that the navigation links in the header work correctly and take you to the appropriate pages.

Test Form Validation

Try submitting the note form with empty fields to ensure validation works correctly.

Verify that error messages are displayed appropriately.

Django Admin: Don't forget that you can also use the admin interface at http://127.0.0.1:8000/admin/ to manage your notes. Log in with the superuser credentials you created earlier.
Testing in Different Browsers: It's a good practice to test your application in different browsers to ensure compatibility. Try opening your app in Chrome, Firefox, Safari, or Edge to verify that it looks and works correctly across different browsers.

10. Deployment Options (Overview)

Once you've built and tested your Django application, you might want to deploy it to make it accessible to others. Here's a brief overview of deployment options.

Preparation for Deployment

Before deploying, you need to make some changes to your settings:

# In settings.py

# Set DEBUG to False in production
DEBUG = False

# Set ALLOWED_HOSTS to your domain(s)
ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']

# Configure a production database (e.g., PostgreSQL)
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'your_database_name',
        'USER': 'your_database_user',
        'PASSWORD': 'your_database_password',
        'HOST': 'localhost',
        'PORT': '',
    }
}

# Set a secure SECRET_KEY
SECRET_KEY = 'your-secret-key'  # Use environment variables for this in practice

# Configure static files
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'

Deployment Platforms

PythonAnywhere

A beginner-friendly platform specifically designed for Python and Django applications.

  • Free tier available
  • Easy to set up
  • Good for beginners
Learn more

Heroku

A platform as a service (PaaS) that enables developers to build, run, and operate applications.

  • Free tier available (with limitations)
  • Good scaling options
  • Extensive documentation
Learn more

DigitalOcean

Cloud infrastructure provider that offers Droplets (virtual machines) and App Platform.

  • More control over your server
  • Requires more setup knowledge
  • Affordable pricing
Learn more

AWS, Google Cloud, Azure

Major cloud platforms offering various services for deploying web applications.

  • Extensive feature sets
  • Highly scalable
  • Steeper learning curve

Various options available

General Deployment Steps

  1. Set up a production database (e.g., PostgreSQL)
  2. Configure your settings for production
  3. Collect static files: python manage.py collectstatic
  4. Choose and set up a web server (e.g., Gunicorn, uWSGI)
  5. Configure a reverse proxy (e.g., Nginx, Apache)
  6. Set up HTTPS using a certificate (e.g., Let's Encrypt)
  7. Deploy your code to the server
  8. Start your application
Deployment Recommendation: For beginners, PythonAnywhere or Heroku are good choices due to their simpler setup processes and good documentation. As you become more experienced, you might want to explore other options that give you more control over your environment.

11. Final Project Summary and Checklist

What We've Built

Congratulations! You've successfully built a simple Django web application that allows users to:

  • View a styled home page with links to create and view notes
  • Create new notes with a title and content
  • View a list of all notes

Along the way, you've learned:

  • How to set up a Django development environment
  • How to create a Django project and app
  • How to define models and work with databases
  • How to create views, templates, and URLs
  • How to handle forms and user input
  • How to style your application with Bootstrap
  • How to test your application
  • An overview of deployment options

Project Checklist

Use this checklist to make sure you've completed all the necessary steps:

Next Steps

You've built a basic Django application, but there are many ways you can expand it:

Add User Authentication

Allow users to register, log in, and have their own private notes.

Add CRUD Operations

Implement functionality to update and delete notes.

Add Categories/Tags

Allow users to categorize notes and filter by category.

Add Rich Text Editing

Implement a rich text editor for note content.

Add Search Functionality

Allow users to search through their notes.

Add API

Create a REST API for your notes app using Django REST framework.

Resources for Further Learning

Congratulations!

You've completed the Django tutorial and built your first web application!

Continue exploring Django and building more complex applications to enhance your skills.