Building a Simple To-Do List App with Django

Hello there, aspiring web developers and productivity enthusiasts! Are you looking for a fun and practical way to dive into web development? Or perhaps you want to build a simple tool to keep track of your daily tasks? Today, we’re going to combine these goals by building a basic To-Do List application using one of the most popular and powerful web frameworks out there: Django.

What is a To-Do List App?

At its core, a To-Do List app is a tool that helps you manage your tasks. You can add new tasks, mark them as complete, and sometimes even delete them. It’s a fantastic project for beginners because it involves fundamental web development concepts like storing data, displaying it, and allowing users to interact with it.

Why Django?

Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. It’s often called a “batteries-included” framework because it comes with many features built-in, like an administrative panel, database abstraction layer (ORM), and authentication system. This makes it easier to get started and build robust applications quickly, even for beginners.

Supplementary Explanation:
* Web Framework: A collection of tools and libraries that provide a structure for building websites. Think of it like a toolkit for creating web applications.
* Python: A widely used, easy-to-read programming language.
* ORM (Object-Relational Mapper): A system that lets you interact with your database using Python code instead of writing complex SQL queries directly. It makes database operations much simpler!

Let’s roll up our sleeves and start building!

Prerequisites

Before we begin, make sure you have:

  • Python 3: Installed on your computer. You can download it from python.org.
  • Basic command line knowledge: Knowing how to navigate directories and run commands in your terminal or command prompt.

Step 1: Setting Up Your Environment

First, let’s create a dedicated space for our project to keep things organized. This is where virtual environments come in handy.

Supplementary Explanation:
* Virtual Environment: An isolated environment for Python projects. It allows you to manage dependencies for different projects without conflicts. Imagine having a separate toolbox for each project, ensuring tools for one project don’t interfere with another.

  1. Create a Project Folder:
    bash
    mkdir mytodolist
    cd mytodolist

  2. Create a Virtual Environment:
    bash
    python -m venv venv

  3. Activate the Virtual Environment:

    • On macOS/Linux:
      bash
      source venv/bin/activate
    • On Windows:
      bash
      venv\Scripts\activate

      You’ll see (venv) at the beginning of your command prompt, indicating that the virtual environment is active.
  4. Install Django:
    bash
    pip install Django

Step 2: Starting a New Django Project

Now that Django is installed, let’s create our first Django project. A Django project is a collection of settings and applications that make up a particular website.

  1. Start the Project:
    bash
    django-admin startproject todo_project .

    (The . at the end means “create the project in the current directory.”)

  2. Run Migrations: Django comes with a default set of configurations for things like user authentication. We need to apply these to our database.
    Supplementary Explanation:

    • Migrations: Django’s way of managing changes to your database schema (the structure of your data). When you make changes to your models (which we’ll do soon), Django generates migration files to update your database accordingly.
      bash
      python manage.py migrate
  3. Start the Development Server:
    bash
    python manage.py runserver

    Open your web browser and go to http://127.0.0.1:8000/. You should see a “The install worked successfully! Congratulations!” page. This means your Django project is up and running! Press Ctrl+C in your terminal to stop the server for now.

Step 3: Creating a Django App

Within a Django project, you typically create one or more apps. An app is a self-contained module that does one specific thing – in our case, manage to-do items.

  1. Create the To-Do App:
    bash
    python manage.py startapp todo

    This creates a new folder named todo with several files inside it.

  2. Register Your App: Django needs to know about your new app. Open todo_project/settings.py and find the INSTALLED_APPS list. Add 'todo' to it:

    “`python

    todo_project/settings.py

    INSTALLED_APPS = [
    ‘django.contrib.admin’,
    ‘django.contrib.auth’,
    ‘django.contrib.contenttypes’,
    ‘django.contrib.sessions’,
    ‘django.contrib.messages’,
    ‘django.contrib.staticfiles’,
    ‘todo’, # Add your app here
    ]
    “`

Step 4: Defining Your To-Do Item Model

A model is like a blueprint for the data you want to store in your database. For our To-Do list, we’ll need a model for a “ToDoItem.”

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

from django.db import models

class ToDoItem(models.Model):
    title = models.CharField(max_length=200) # A short text field for the task name
    description = models.TextField(blank=True, null=True) # A longer text field, optional
    created_at = models.DateTimeField(auto_now_add=True) # Automatically sets the creation time
    completed = models.BooleanField(default=False) # A checkbox to mark if the task is done

    def __str__(self):
        return self.title # How this object will be represented (as its title)

Supplementary Explanation:
* models.Model: The base class for all Django models.
* CharField: Stores a small amount of text (like a title). max_length is required.
* TextField: Stores a larger amount of text (like a description). blank=True, null=True means it’s optional.
* DateTimeField: Stores a date and time. auto_now_add=True means it automatically sets the current time when the item is created.
* BooleanField: Stores a true/false value (like whether a task is completed). default=False sets its initial value.
* __str__(self): A special method that defines how an object of this model should be displayed as a string (e.g., in the Django admin).

Step 5: Applying Model Changes (Again)

Whenever you change your models, you need to tell Django to create new migrations and then apply them to your database.

  1. Make Migrations:
    bash
    python manage.py makemigrations todo

    This command creates a migration file inside your todo/migrations folder, describing the changes you made.

  2. Apply Migrations:
    bash
    python manage.py migrate

    This command applies the changes described in the migration file to your database, creating the ToDoItem table.

Step 6: Creating an Admin Interface (Optional but Recommended)

Django comes with a powerful administrative interface that allows you to manage your data without writing any frontend code. Let’s make our ToDoItem accessible there.

  1. Create a Superuser: This is an admin user for your Django project.
    bash
    python manage.py createsuperuser

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

  2. Register Your Model in Admin: Open todo/admin.py and add:

    “`python

    todo/admin.py

    from django.contrib import admin
    from .models import ToDoItem # Import your model

    admin.site.register(ToDoItem) # Register it with the admin site
    “`

  3. View the Admin Panel:
    bash
    python manage.py runserver

    Go to http://127.0.0.1:8000/admin/ in your browser. Log in with the superuser credentials you just created. You should now see “ToDo Items” under “TODO”! You can add, edit, and delete items right from this interface.

Step 7: Building the Views

A view is a Python function or class that receives a web request and returns a web response. It’s where the logic for displaying data and handling user input lives.

Open todo/views.py and add the following:

from django.shortcuts import render, redirect
from .models import ToDoItem
from django.forms import ModelForm

class ToDoItemForm(ModelForm):
    class Meta:
        model = ToDoItem
        fields = ['title', 'description', 'completed'] # Fields to include in the form

def todo_list(request):
    items = ToDoItem.objects.all().order_by('-created_at') # Get all ToDo items, newest first
    return render(request, 'todo/todo_list.html', {'items': items})

def add_todo(request):
    if request.method == 'POST':
        form = ToDoItemForm(request.POST)
        if form.is_valid():
            form.save() # Save the new ToDo item to the database
            return redirect('todo_list') # Redirect to the list view
    else:
        form = ToDoItemForm() # Create an empty form for GET requests
    return render(request, 'todo/add_todo.html', {'form': form})

Supplementary Explanation:
* render(request, template_name, context): A Django shortcut that takes a request, loads a template, fills it with data from the context dictionary, and returns an HttpResponse object.
* redirect(url_name): A shortcut to redirect the user to a different URL.
* ModelForm: A special type of form in Django that can be directly linked to a model, making it easy to create forms for your database objects.
* ToDoItem.objects.all(): This is our ORM in action! It fetches all ToDoItem objects from the database.

Step 8: Setting Up URLs

Now we need to connect our views to specific web addresses (URLs).

  1. Create todo/urls.py: This file will define the URLs for our todo app.

    “`python

    todo/urls.py

    from django.urls import path
    from . import views # Import views from the current directory

    urlpatterns = [
    path(”, views.todo_list, name=’todo_list’), # URL for listing tasks
    path(‘add/’, views.add_todo, name=’add_todo’), # URL for adding a new task
    ]
    “`

  2. Include App URLs in Project URLs: Open todo_project/urls.py and add an include statement.

    “`python

    todo_project/urls.py

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

    urlpatterns = [
    path(‘admin/’, admin.site.urls),
    path(‘todos/’, include(‘todo.urls’)), # Include your todo app’s URLs here
    ]
    ``
    Now, when someone visits
    http://127.0.0.1:8000/todos/, Django will look at ourtodoapp'surls.py` for matching paths.

Step 9: Crafting Templates

Templates are HTML files that Django uses to display web pages. They can include dynamic content using Django’s template language.

  1. Create a templates Directory: Inside your todo app directory, create a new folder named templates, and inside that, another folder named todo. This structure (app_name/templates/app_name/) is a best practice to avoid template name conflicts.

    mytodolist/
    └── todo_project/
    └── todo/
    ├── migrations/
    ├── templates/
    │ └── todo/
    │ ├── add_todo.html
    │ └── todo_list.html
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── models.py
    ├── tests.py
    ├── urls.py # Newly created
    └── views.py
    └── venv/
    └── manage.py

  2. Create todo/templates/todo/todo_list.html:

    “`html

    <!DOCTYPE html>




    My To-Do List


    My To-Do List

    <a href="{% url 'add_todo' %}">Add New Task</a>
    
    {% if items %}
        <ul>
            {% for item in items %}
                <li class="{% if item.completed %}completed{% endif %}">
                    <div>
                        <strong>{{ item.title }}</strong>
                        {% if item.description %}<br><small>{{ item.description }}</small>{% endif %}
                        <br><small>Created: {{ item.created_at|date:"M d, Y" }}</small>
                    </div>
                    <div>
                        {% if item.completed %}
                            <span>&#x2713; Done</span>
                        {% else %}
                            <span>Not Done</span>
                        {% endif %}
                    </div>
                </li>
            {% endfor %}
        </ul>
    {% else %}
        <p>No tasks yet! Time to add some.</p>
    {% endif %}
    



    “`

  3. Create todo/templates/todo/add_todo.html:

    html
    <!-- todo/templates/todo/add_todo.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Add New To-Do</title>
    <style> /* Basic styling */
    body { font-family: sans-serif; margin: 20px; }
    form div { margin-bottom: 10px; }
    label { display: block; margin-bottom: 5px; font-weight: bold; }
    input[type="text"], textarea { width: 300px; padding: 8px; border: 1px solid #ccc; border-radius: 4px; }
    input[type="checkbox"] { margin-right: 5px; }
    button { background-color: #28a745; color: white; padding: 10px 15px; border: none; border-radius: 4px; cursor: pointer; }
    button:hover { background-color: #218838; }
    a { text-decoration: none; color: #007bff; margin-left: 10px; }
    a:hover { text-decoration: underline; }
    </style>
    </head>
    <body>
    <h1>Add New To-Do Item</h1>
    <form method="post">
    {% csrf_token %} {# Security token required for forms #}
    {{ form.as_p }} {# Renders the form fields as paragraphs #}
    <button type="submit">Add Task</button>
    <a href="{% url 'todo_list' %}">Cancel</a>
    </form>
    </body>
    </html>

    Supplementary Explanation:
    * {% csrf_token %}: A security feature in Django that protects against Cross-Site Request Forgery attacks. Always include it in your forms!
    * {{ form.as_p }}: A convenient way to render all form fields as paragraphs (<p> tags).
    * {% url 'name' %}: A Django template tag that generates a URL based on the name you gave to the URL pattern in urls.py.

Congratulations! You’ve Built a Basic To-Do List App!

Restart your Django development server if it’s not running:

python manage.py runserver

Now, navigate to http://127.0.0.1:8000/todos/ in your browser. You should see your To-Do list! You can add new tasks by clicking the “Add New Task” link.

What’s Next?

You’ve built the foundation of a functional To-Do list. Here are some ideas to expand your app:

  • Styling: Make it look nicer with custom CSS or a frontend framework like Bootstrap.
  • Update/Delete Functionality: Add buttons to edit existing tasks or delete them. This involves creating new views and URL patterns.
  • User Authentication: Allow different users to have their own separate To-Do lists.
  • Task Prioritization: Add fields to assign priority levels to tasks.

Building this simple app is a great first step into the world of Django and web development. Keep experimenting, keep learning, and happy coding!

Comments

Leave a Reply